✅
Nginx on Dockerでリバースプロキシが動かない時のチェックリスト
Docker
でアプリケーションサーバー(Node.js
)のコンテナを立てて、Nginx
のコンテナからリバースプロキシしようとして、かなりハマったので、その時の体験と解決方法を共有します。
何をやりたかったのか
-
Docker
でNginx
とNode.js
(アプリケーションサーバー)のコンテナを建てていた。 -
Node.js
へのリクエスト前にNginx
を置き、リクエストをリバースプロキシさせたい。
発生していたエラー
- Nginxから指定しているホスト(アプリケーションサーバー)に接続できないというエラー
no live upstreams while connecting to upstream, client: 192.168.144.1, server: localhost, request: "GET /api/ HTTP/1.1", upstream: "http://localhost/api/health", host: "localhost"
上手く行かない時にどんな状態だったか
- アプリケーションサーバー(Node.js)は起動している
curl http://localhost:4000/api/health
{"status":"ok","response":{"now":"2024-06-28T09:46:03.360Z"}}%
- Nginxから
proxy_pass
に設定すると、502 Bad Gatewayになる。
location /api/ {
proxy_pass http://localhost:4000/api/; -> 502 Bad Gateway
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
-
nginx -t
でconfigを構文チェックをしても設定ファイル上ではエラーは起こっていない。
docker exec -it nginx bash
root@:/# nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
結論
-
Dockerのネットワーク機能を利用する
Dockerコンテナ間(今回のケースではNginx
とNode.js
)でlocalhost
の通信はできないため、Dockerのネットワーク内で通信する(コンテナ名を指定するなどが)必要があります。
もし、通信したいコンテナ同士のdocker-compose.yml
が分かれている場合は、同一のネットワークであること明示的に指定(network
オプション)を記載します。
location /api/ {
proxy_pass http://{Container_name}:4000/api/; # コンテナ名を指定する
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
まとめ
- Stack Overflowなどでエラーメッセージを検索しまくりましたが、一向に解決策が見つからず頭を抱えていました。なんとなくNginxのコンテナの中に入り、
curl http://localhost:4000
を叩いた瞬間に気づきました。Nginxのエラーを調べまくっていましたが、Docker上で動かしていることに意識が向いていなかったのが原因ですね。 - もし、Docker上でNginxのコンテナから別のDockerコンテナに対して接続を行いたい場合は、Dockerネットワークを正しく設定しているか確認することを強くお勧めします...。
この方法が皆さんの参考になれば幸いです。
最後に、Nginx on Dockerでリバースプロキシがうまく動作しない場合のチェックリストを記載して記事を締めます。
チェックリスト
✅ リバースプロキシするサーバーは起動しているか?コンテナ外からcurlコマンドなどで通信を確認できるか?
✅ configファイルに記載しているポートやホストに間違いがないか?
✅ nginx -t
でconfigを構文チェックをしても設定ファイル上ではエラーは起こっていないか?
✅ Dockerコンテナ間での通信には、localhost
や127.0.0.1
ではなく、コンテナ名やDockerネットワークを使用しているか?
✅ docker-compose.yml
が使用されている場合、適切なネットワーク設定がされているか?特に、異なるコンテナが同じネットワーク上にあることを確認しているか?
✅ proxy_pass
のURLが正しく設定されているか?特に、末尾のスラッシュ(/
)の有無が意図した通りになっているか?
✅ Nginxのログを確認して、リバースプロキシの試みがどのように失敗しているか、具体的なエラーメッセージを確認しているか?
✅ セキュリティグループやファイアウォールの設定が、コンテナ間通信を妨げていないか?
Discussion