🐟

Docker環境で vue.config.js の proxy が動かなかった

2022/06/27に公開

大ハマリしてしまったのでネタに。

事象

vue.config.js に proxyの設定を記述して、FrontendとBackendを同一のポートで動かそうとしたところ、想定した挙動にならなかった。
https://cli.vuejs.org/config/#devserver-proxy

前提
下記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 で立ち上げてリクエストを送ると期待する挙動になりました。

GitHubで編集を提案

Discussion