更新: 2026年03月 · 10 分で読める · 5,067 文字
Nginx 502 Bad Gatewayの3つの原因と実践的な解決手順
Nginxで502 Bad Gatewayエラーが発生する場合、アップストリームサーバーへの通信失敗が原因です。この記事では、エラーログの読み方から具体的な解決手順まで、本番環境ですぐに使える診断方法と対策を紹介します。
502 Bad Gatewayが発生する3つの主な原因
原因1: アップストリームサーバーがダウンまたは応答がない
最も一般的な原因は、バックエンドのアプリケーションサーバー(Express、Django、Unicornなど)が起動していないか、ポート番号が間違っている場合です。Nginxがリクエストを転送しようとしたときに接続できないため、502エラーが返されます。
確認コマンド:
# アップストリームサーバーの状態確認(例:127.0.0.1:3000)
netstat -tlnp | grep 3000
# または
ss -tlnp | grep 3000
# ポートが開いているか確認
curl -v http://127.0.0.1:3000/
原因2: Nginxの設定ミス(upstreamブロックの誤設定)
nginx.confまたはサイト設定ファイルでアップストリームサーバーのアドレスやポートを間違って指定している場合、Nginxは接続できず502エラーが返されます。
設定ファイルの確認:
# Nginx設定の構文チェック
nginx -t
# 設定ファイルの内容確認
cat /etc/nginx/nginx.conf
cat /etc/nginx/sites-enabled/default # またはあなたのサイト設定
原因3: アップストリームサーバーのタイムアウトまたはクラッシュ
アプリケーションが処理に時間がかかるか、メモリ不足でクラッシュしている場合、Nginxはタイムアウトして502エラーを返します。また、アプリケーションのエラーログに大量のエラーが出ていることがあります。
実践的な診断と解決手順
ステップ1: Nginxのエラーログを確認する
まずはNginxのエラーログを確認し、具体的なエラーメッセージを把握します。
# エラーログの末尾を表示
tail -50 /var/log/nginx/error.log
# リアルタイムでログを監視
tail -f /var/log/nginx/error.log
# 502に関連するエラーのみを抽出
grep "502\|upstream" /var/log/nginx/error.log | tail -20
エラーログには以下のようなメッセージが表示されます:
connect() failed (111: Connection refused)→ アップストリームサーバーが起動していないupstream timed out (110: Connection timed out)→ サーバーが応答遅い、またはタイムアウト設定が短いno live upstreams→ すべてのアップストリームサーバーがダウンしている
ステップ2: アップストリームサーバーの健全性をテストする
Nginxサーバーからアップストリームサーバーに直接接続可能か確認します。
# アップストリームサーバーのレスポンスを確認
curl -v http://localhost:3000/health
# ヘッダーのみを取得
curl -I http://localhost:3000/
# タイムアウトを指定してテスト
curl --max-time 5 -v http://localhost:3000/
# ソケットレベルでの接続確認
timeout 3 bash -c "echo > /dev/tcp/127.0.0.1/3000" && echo "Connection OK" || echo "Connection FAILED"
ステップ3: Nginx設定ファイルを検査する
以下は一般的なNginx設定例です。あなたの設定ファイル(/etc/nginx/sites-enabled/defaultなど)と比較してください。
upstream backend {
# アップストリームサーバーの指定
server 127.0.0.1:3000;
server 127.0.0.1:3001;
# タイムアウト設定(デフォルト60秒)
keepalive 32;
}
server {
listen 80;
server_name example.com;
location / {
# upstreamの名前を指定
proxy_pass http://backend;
# 重要: Hoストヘッダーを転送
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;
# タイムアウト設定を明示的に指定(秒単位)
proxy_connect_timeout 10s;
proxy_send_timeout 30s;
proxy_read_timeout 30s;
}
}
設定を変更した後は必ず構文チェックとリロードを実行します:
# 構文チェック
sudo nginx -t
# 設定のリロード(グレースフルリスタート)
sudo systemctl reload nginx
# または
sudo service nginx reload
ステップ4: プロセスとリソースを確認する
アップストリームサーバー(Node.jsやPythonなど)が実際に起動しているか確認します。
# Node.jsプロセスの確認
ps aux | grep node
# ポート使用状況の確認
lsof -i :3000
# リソース使用状況(メモリ不足がないか確認)
free -h
df -h
# アップストリームサーバーのログを確認
journalctl -u myapp -n 50 # systemdで管理している場合
tail -50 /var/log/myapp.log
ハマりポイント: proxy_set_headerを忘れずに設定する
Nginxのデフォルト設定ではHostヘッダーなどが転送されないため、アプリケーション側で問題が発生することがあります。以下のヘッダーは必ず設定してください:
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;
すぐに試せる総合的な設定例
以下は本番環境で推奨される設定例です。このファイルを/etc/nginx/sites-available/mysiteに保存し、シンボリックリンクを作成してください。
upstream app_backend {
# 複数のバックエンドサーバーを指定(負荷分散)
server 127.0.0.1:3000 max_fails=3 fail_timeout=30s;
server 127.0.0.1:3001 max_fails=3 fail_timeout=30s;
# サーバーがダウンした場合に他のサーバーにフェイルオーバー
# max_fails: 何回失敗したらサーバーをダウンと判定するか
# fail_timeout: ダウンと判定してから何秒待つか
}
server {
listen 80;
server_name example.com www.example.com;
# ログ設定
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log warn;
location / {
proxy_pass http://app_backend;
# ホストヘッダーとクライアント情報を転送
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;
# タイムアウト設定(秒単位)
proxy_connect_timeout 10s; # 接続待機時間
proxy_send_timeout 30s; # リクエスト送信待機時間
proxy_read_timeout 30s; # レスポンス受信待機時間
# バッファリング設定(大容量ファイル対応)
proxy_buffering on;
proxy_buffer_size 4k;
proxy_buffers 8 4k;
# キープアライブ設定
proxy_http_version 1.1;
proxy_set_header Connection "";
}
# ヘルスチェック用エンドポイント
location /health {
access_log off;
proxy_pass http://app_backend;
proxy_connect_timeout 5s;
proxy_read_timeout 5s;
}
}
設定をシステムに反映します:
# 設定ファイルをsites-enabledにリンク
sudo ln -s /etc/nginx/sites-available/mysite /etc/nginx/sites-enabled/mysite
# デフォルト設定を無効化(必要に応じて)
sudo rm /etc/nginx/sites-enabled/default
# 構文チェック
sudo nginx -t
# Nginxをリロード
sudo systemctl reload nginx
502エラーが解決しない場合のトラブルシューティング
ファイアウォール設定を確認する
Nginxとアップストリームサーバーが同じサーバー上にない場合、ファイアウォールが通信をブロックしている可能性があります:
# UFWを使用している場合
sudo ufw allow 3000
# iptablesを使用している場合
sudo iptables -A INPUT -p tcp --dport 3000 -j ACCEPT
# 接続確認(別サーバーから)
telnet backend-server-ip 3000
アップストリームサーバーのリソース確認
メモリ不足やCPU不足でアプリケーションがクラッシュしていることがあります:
# メモリ使用率が高いプロセスを表示
ps aux --sort=-%mem | head -10
# CPUスパイクを確認
top -b -n 1 | head -20
# Dockerを使用している場合
docker stats
Nginxのキャッシュをクリアする
502エラーがキャッシュされている可能性があります:
# アクセスログからキャッシュの有無を確認
tail -50 /var/log/nginx/access.log | grep "HIT\|MISS"
# Nginxのキャッシュをクリア(設定されている場合)
sudo rm -rf /var/cache/nginx/*
# Nginxをリロード
sudo systemctl reload nginx
使うべき場面と使うべきでない場面
Nginxのリバースプロキシを使うべき場面:
- 複数のアプリケーションサーバーに対して負荷分散したい
- HTTPSターミネーションを集約したい
- セキュリティ上の理由でアプリケーションサーバーを直接公開したくない
- スタティックファイル配信を高速化したい
Nginxを使うべきでない場面:
- シンプルなスタンドアロンアプリケーション(複雑さが増す)
- 開発環境(セットアップの手間が増える)
- 特定の言語のアプリケーションサーバー(Flask、Express)が既にそれらの機能を持っている場合
類似ツールとの比較
Nginxとその他のリバースプロキシ:
- Apache:リバースプロキシ機能は持つが、Nginxより消費メモリが多い
- Caddy:自動HTTPS化が便利だが、プロダクション環境ではNginxの方が実績が豊富
- HAProxy:ロードバランシングに特化しており、複雑な負荷分散設定に向いている
よくある質問
Q: 502エラーが断続的に発生します。原因は何ですか?
A: 断続的な502は、アプリケーションサーバーがたまに落ちている、またはメモリリークで徐々に遅くなっ
おすすめDevOpsリソース
- Docker Documentation Official Docker and Docker Compose reference.
- Kubernetes Docs Official K8s documentation. Great for understanding concepts.
- GitHub Actions Docs Official guide for CI/CD workflows.