【Vite】proxyでlocalhostを設定するとエラーになるお話

## 事象
```vite.config.ts```のproxy設定に```localhost:8080```を設定すると接続エラーが発生したので、調査とそのメモ

```ts:vite.config.ts
      '/proxy': {
        target: `http://localhost:8080`,
        changeOrigin: true,
        rewrite: (path) => path.replace(/^\/proxy/, ''),
      }
```

```:エラーメッセージ
Error: connect ECONNREFUSED 127.0.0.1:8080
    at TCPConnectWrap.afterConnect [as oncomplete] (node:net:1595:16)
```

## 開発環境
- BE: Go
- FE: Vue + TS + Vite
- 実行環境: Docker(BE,FEで1コンテナずつ)

## 最初に出てきた情報
エラーメッセージでググるとnodeのバージョンによって```localhost```をipに変換できない関連の情報がたくさん出てくる
[例えばこんな感じ](https://github.com/vitejs/vite/discussions/7620)
```diff_typescript:vite.config.ts
      '/proxy': {
-        target: `http://localhost:8080`,
+        target: `http://127.0.0.1:8080`,
        changeOrigin: true,
        rewrite: (path) => path.replace(/^\/proxy/, ''),
      }
```

ただしエラーメッセージを見ると正しく```127.0.0.1```と読み替えているので恐らく関係ない
(実際に変更したけど変化無し)

## Docker環境の影響？
調べているとDocker環境の場合、```localhost```の向き先がBEコンテナではなく、FEコンテナを見に行っているらしい

### ネットワークの変更
今回はBEとFEでそれぞれdocker-compose.ymlを作成し、別々のネットワークでコンテナを立ち上げているため、BEのネットワークにFEを追加する
(docker-compose.ymlを１つにしたり、ネットワークだけうまく編集するなどやり方はたくさんあると思うが、色々と面倒なので今回は思いついた一番手っ取り早い方法を採用)

まずはBEのネットワークを調べる
```
docker inspect backendのコンテナ名
```

ネットワーク名をメモ
```
"Networks": {
                "backend_default": {
                    "IPAMConfig": null,
                    "Links": null,
                    "Aliases": [
                        "d4a77d324cd7",
                        "golang"
                    ],
                    "NetworkID": "395409fc5ab4c3bd05d00d74dda5d9473402201bf98cc89a480752fa6b4ed63e",
                    "EndpointID": "b03a72b9262171f7c2dcf45a938d073caa794d5ab0d075a07495515c57002122",
                    "Gateway": "172.21.0.1",
                    "IPAddress": "172.21.0.2",
                    "IPPrefixLen": 16,
                    "IPv6Gateway": "",
                    "GlobalIPv6Address": "",
                    "GlobalIPv6PrefixLen": 0,
                    "DriverOpts": null
                }
```
次にFE側のdocker-compose.ymlを修正
```diff_yaml:docker-compose.yml
version: '3'
services:
  frontend:
    build:
      context: .
      dockerfile: Dockerfile
    tty: true
    volumes:
      - .:/app
    ports:
      - 5173:5173
+    networks:
+      - backend_default
+
+ networks:
+  backend_default:
+    external: true
```

コンテナを再起動
```
docker-compose down
docker-compose up -d
```

ネットワークが変更されていることを確認
```
docker inspect Frontendのコンテナ名
```

```
"Networks": {
                "backend_default": {
                    "IPAMConfig": null,
                    "Links": null,
                    "Aliases": [
                        "3355adbacdfc"
                    ],
                    "NetworkID": "395409fc5ab4c3bd05d00d74dda5d9473402201bf98cc89a480752fa6b4ed63e",
                    "EndpointID": "87b45d6c8fddf32e7f86886551442036364028579d2f0f1d0442d3366fa4c917",
                    "Gateway": "172.21.0.1",
                    "IPAddress": "172.21.0.3",
                    "IPPrefixLen": 16,
                    "IPv6Gateway": "",
                    "GlobalIPv6Address": "",
                    "GlobalIPv6PrefixLen": 0,
                    "DriverOpts": null
                }
```

これでコンテナ側の更新は終了

### アプリ側の修正
ここまでくればあとは```vite.config.ts```を修正してあげるだけ
```diff_typescript:vite.config.ts
      '/proxy': {
-        target: `http://localhost:8080`,
+        target: `http://backendコンテナ名:8080`,
        changeOrigin: true,
        rewrite: (path) => path.replace(/^\/proxy/, ''),
      }
```

アプリを立ち上げ確認すると、エラーメッセージが出ず正しく通信ができている！

```
yarn run dev 
```

## まとめ
Dockerのlocalhost関連は毎回引っかかっているので、そろそろつまずかないように成りたい。。

## 参考
- [Vite proxy error ECONNREFUSED does not change the browser request from pending. #7620](https://github.com/vitejs/vite/discussions/7620)
- [Docker環境で vue.config.js の proxy が動かなかった](https://zenn.dev/kettle_tomorrow/articles/df3bba621a1e43)
- [Dockerでコンテナ間通信を行う方法](https://zenn.dev/tns_00/articles/docker-communicate-with-containers)
- [Compose の ネットワーク機能](https://docs.docker.jp/compose/networking.html#comopse-use-a-pre-existing-network)