環境
- macOS 10.14.4
- docker-compose version 1.23.2
- webpack-dev-server 3.7.2
- webpack 4.37.0
フロントエンド(webpack-dev-server)、バックエンドをそれぞれDocker Compose上にコンテナとして起動して開発していた際にハマったお話。
事象
webpack-dev-serverはホストするjs内で発行されるHTTPリクエストをプロキシすることができる
webpack.config.js
を以下のように設定(抜粋)- APIサーバーは5000番ポートを開いているとする
devServer: { contentBase: path.join(__dirname, 'dist'), compress: true, port: 8080, historyApiFallback: true, proxy: { '/api': 'http://localhost:5000', }
- 上記設定を反映したwebpack-dev-serverを起動し(
docker-compose up
)、実際にlocalhost:8080にアクセスしてfetch('/api')...
をブラウザから実行すると、webpack-dev-serverが以下のエラーを出力した
[HPM] Error occurred while trying to proxy request /api from localhost:8080 to http://localhost:5000 (ECONNREFUSED) (https://nodejs.org/api/errors.html#errors_common_system_errors)
- httpレスポンスは以下(抜粋)
504 Gateway Timeout Error occured while trying to proxy to: localhost:8080/api
原因
Docker Compose上のコンテナが参加するネットワークでは、
docker-compose.yml
上のサービス名で名前解決が行われるため。従って、
webpack.config.js
を下記のように書き換えると上手くいく
... proxy: { '/api': 'http://api:5000', }
- なお、
docker-compose.yml
では以下のようにサービス名をapi
としている
version: "3.4" services: api: build: context: ./api ...
敗因
- 書いてみるとこれだけのことだが、多分2,3時間ぐらいハマっていた
- サービス名で名前解決ができること自体はDocker Composeのドキュメントに書いてあることだし、以前から知っていた。なぜ気づけなかったのか...
- 多分だが、ブラウザからDocker Compose上のwebpack-dev-serverにアクセスする際は、
- のでwebpack-dev-serverが動作しているのがDocker Compose上であることを忘れていたというか、しっかり認識できていなかったような気がする。
- また、Docker Compose上のネットワーク内のコンテナ間もlocalhostで通信できるようなイメージだったのも原因かもしれない。
- あと、ステータスコード504 Gateway Timeoutの理解が不足している感もある。webpack-dev-serverがlocalhost:5000が存在しないためにレスポンスを得られない→ポート5000で動作しているはずのHTTPサーバーのログを確認する→ログがない→接続先がおかしい?というような手順をスムーズに踏めたら良かった。
- Goで書いているHTTPサーバは外部ファイルへのログ出力を未実装で、結局調査のために書いたんだけど、ここを面倒くさがらずに早く実行するべきだったかな...