Docker環境で vue.config.js の proxy が動かなかった
大ハマリしてしまったのでネタに。
事象
vue.config.js
に proxyの設定を記述して、FrontendとBackendを同一のポートで動かそうとしたところ、想定した挙動にならなかった。
前提
下記URLでそれぞれコンテナを動かしていた。
Frontend: http://localhost:8080
Backend: http://localhost:3000
期待する挙動
http://localhost:8080/api
配下へのリクエストが、Backendのコンテナhttp://localhost:3000/api
に飛んでほしい。
devServer: {
proxy: {
'^/api': {
target: 'http://localhost:3000',
}
}
}
実際の挙動(エラー)
Proxy経由リクエストが通らない。
Proxy error: Could not proxy request /api/v1/login from localhost:8080 to http://localhost:3000 (ECONNREFUSED).
ログに書き込まれたnodejsのエラーページを見に行ったところ、プロキシの向き先のサーバが動作していないっぽい。Backendのコンテナ(http://localhost:3000/api
)はちゃんと立ち上がっている。
なぜこのような挙動になったか
今回の環境はDocker上で動かしていたため、localhost
の向き先が自分の想定通りではなかったことが原因だった。
ブラウザ(手元のMac)からURLを叩く場合は、 ポートフォワードにより同じlocalhostへのアクセスでもポートごとにFrontendとBackendの振り分けを行ってくれる。
が、プロキシのプログラムは手元のMacではなくFrontendのコンテナの中で動作するために上記の挙動にはならない。
localhost:3000は、Frontendのコンテナのポート3000を見に行っている
よう。Frontendのコンテナのポート3000は動作していないのでECONNREFUSEDのエラーが発生していた。
対応策
前置きが長くなったが対応策。
devServer: {
proxy: {
'^/api': {
target: 'http://backend:3000',
}
}
}
localhost
の代わりに コンテナのサービス名
を書いてあげる。
一度コンテナを停止させた後、 docker compose up
で立ち上げてリクエストを送ると期待する挙動になりました。
Discussion