Nginx で『502 Bad Gateway』が出た時の原因特定フローチャートと速攻解決ガイド

この記事は約16分で読めます。
  1. 1. 突然の502 Bad Gateway…!画面に広がる「白い絶望」
  2. 2. そもそも502 Bad Gatewayとは?(仕組みを理解する)
    1. 502エラーは「不通の伝言ゲーム」
  3. 3. 【完全ガイド】10分で復旧!502原因特定4ステップフローチャート
    1. STEP 1:Nginxのエラーログを即チェックする
    2. STEP 2:バックエンド(PHP / Node / Python)の生存確認
      1. 【PHP-FPMの場合】
      2. 【Node.js(PM2等) / Python(Gunicorn等)の場合】
    3. STEP 3:Nginx ⇔ バックエンドの「接続経路」を確認
      1. パターンA:Unixドメインソケットを使用している場合
      2. パターンB:TCPポート(127.0.0.1:9000など)を使用している場合
    4. STEP 4:ポート・ファイアウォール・IP設定の確認
      1. 1. UFW / firewalld(ファイアウォール)の確認
      2. 2. SELinuxの拒否(CentOS / Rocky Linux / AlmaLinux等)
  4. 4. よくある原因と即効解決パターン3選
    1. パターン1:バックエンド(PHP-FPM / Node.js)が落ちている・起動していない
    2. パターン2:ソケットファイルのパーミッション・所有権エラー
    3. パターン3:タイムアウト(処理に時間がかかりすぎている)
  5. 5. 【発展】502エラー検知時にX(旧Twitter)へ自動通知する仕組み
    1. 構成のイメージ
    2. ステップ1:X APIのベアラートークン(またはOAuth 1.0a)を準備
    3. ステップ2:502検知&X自動通知スクリプトを作成
    4. ステップ3:Cronで定期実行
  6. 6. まとめ:焦らず「エラーログ」から辿れば必ず直る!

1. 突然の502 Bad Gateway…!画面に広がる「白い絶望」

WebサイトやAPIの開発中、あるいは運用中のサーバーにアクセスした瞬間、画面にぽつんと表示される無機質なテキスト。

502 Bad Gateway

ブラウザの更新ボタンを何度連打しても、キャッシュをクリアしても、頑固として消えてくれないこの画面。エンジニアなら誰もが一度は冷や汗をかいた経験があるのではないでしょうか。
500エラー(Internal Server Error)ならプログラム内部のバグを疑えば済みますが、502エラーは「Webサーバーと、その奥にいるアプリケーションの『間』で何かが途切れている」というサインです。
原因がWebサーバー(Nginx)側にあるのか、バックエンド(PHP-FPM、Node.js、Pythonなど)側にあるのか、あるいはネットワークやポート設定なのか。調査のポイントが多岐にわたるため、闇雲に設定ファイルをいじると迷子になりがちです。

そこで本記事では、Nginx環境で502 Bad Gatewayが発生した際に、焦らず最速で原因を突き止めるための「4ステップ原因特定フローチャート」をまとめました。
順番にチェックを進めていくだけで、どこで通信が詰まっているのかが10分でクリアになります。画面の前の「白い絶望」を、一緒にサクッと撃退していきましょう!

2. そもそも502 Bad Gatewayとは?(仕組みを理解する)

原因特定に進む前に、まずは「502 Bad Gateway」が一体どういう状態なのか、その仕組みを整理しておきましょう。ここを理解しておくだけで、この後のログ確認や設定調整の理解度が劇的に変わります。

502エラーは「不通の伝言ゲーム」

NginxをWebサーバーとして運用している場合、Nginxは「受付(リバースプロキシ)」の役割を果たしています。
ブラウザからのリクエストを受け取ったNginxは、自分自身でHTMLを生成するのではなく、奥にいる「職人(PHP-FPM、Node.js、Gunicorn/Pythonなど)」に処理を丸投げ(転送)します。

  1. ユーザー:
    ブラウザから「ページを見せて!」とリクエストを送る。
  2. Nginx(受付):
    「はいよ!」と受け取り、奥のバックエンド(職人)に「処理して!」と伝言を渡す。
  3. バックエンド(職人):
    処理を行ってNginxに結果を返す……はずが、返事がない!または不正な応答が返ってきた!
  4. Nginx(受付):
    「奥の職人からまともな返事が来ないや…」と困り果て、ユーザーに「502 Bad Gateway(不正なゲートウェイ)」と報告する。

つまり、502エラーが出ているということは、「Nginx自体は元気に動いてリクエストを受け取れているけれど、その奥にあるバックエンドとの通信でトラブルが起きている」という証拠なのです。

Nginx本体が死んでいる場合(503や接続拒否になる)とは切り分けて考えるのが、解決への第一歩となります。

3. 【完全ガイド】10分で復旧!502原因特定4ステップフローチャート

502エラーが出た際、どこから手を付けるべきか迷わないための実践的な4ステップです。上から順番に確認していきましょう!

STEP 1:Nginxのエラーログを即チェックする

何はともあれ、一番最初にやるべきは「Nginxのエラーログを見る」ことです。502エラーの9割は、このログに答えが直接書いてあります。
まずは以下のコマンドでログの末尾をリアルタイム表示させ、ブラウザでページを更新してみましょう。

Bash
sudo tail -f /var/log/nginx/error.log

ここでよく見かける代表的なエラーメッセージと、その原因は以下の通りです。

  • connect() failed (111: Connection refused)
    → 奥のアプリ(PHP-FPMやNode.js等)が起動していない、またはポート/ソケット番号が違います。
  • no live upstreams while connecting to upstream
    → 転送先のバックエンドサーバーが1つも応答していません。
  • permission denied while connecting to upstream
    → SELinuxやパーミッションの影響で、Nginxがソケットファイルにアクセスできていません。

STEP 2:バックエンド(PHP / Node / Python)の生存確認

STEP 1で「Connection refused」などが出ている場合、そもそも「奥のアプリが停止している」可能性が非常に高いため、プロセスが生きているか確認します。

【PHP-FPMの場合】

Bash
sudo systemctl status php-fpm
# または (バージョン指定の場合)(Alternatively (when specifying a version))
sudo systemctl status php8.2-fpm

【Node.js(PM2等) / Python(Gunicorn等)の場合】

Bash
# Node.js (PM2使用時)(Node.js (when using PM2))
pm2 status

# プロセス全般の確認(Checking all running processes)
ps aux | grep node
ps aux | grep gunicorn

もし inactive (dead) やプロセスが存在しない場合は、単純にアプリが落ちています。sudo systemctl start php-fpmpm2 start などで再起動を試みましょう。

STEP 3:Nginx ⇔ バックエンドの「接続経路」を確認

アプリ自体は動いている(Active)のに502が出る場合は、「Nginxとアプリの間の接続設定(ソケット / IP・ポート)」の不一致を疑います。

Nginxの設定ファイル(/etc/nginx/conf.d/default.conf/etc/nginx/sites-available/default など)を開き、proxy_passfastcgi_pass の記述を確認してください。

パターンA:Unixドメインソケットを使用している場合

Nginxの記述例: fastcgi_pass unix:/var/run/php-fpm/www.sock;

  • 確認ポイント1: 指定した場所に .sock ファイルが実際に存在するか?
  • 確認ポイント2: ソケットファイルの所有権・権限がNginxから読み書きできるようになっているか?

パターンB:TCPポート(127.0.0.1:9000など)を使用している場合

Nginxの記述例: proxy_pass http://127.0.0.1:3000;

  • 確認ポイント1: アプリ側が本当にそのポート(3000や9000)で待受(Listen)しているか?
  • 確認コマンド: sudo netstat -tlpn または sudo ss -tlpn でポートが開いているか確認します。

STEP 4:ポート・ファイアウォール・IP設定の確認

上記3つを確認しても解決しない場合、ネットワークやセキュリティ機能が通信を遮断しているケースがあります。

1. UFW / firewalld(ファイアウォール)の確認

Nginxとバックエンドが別々のサーバーに分かれている場合、ファイアウォールでポートが閉じられていないか確認します。

2. SELinuxの拒否(CentOS / Rocky Linux / AlmaLinux等)

RedHat系のLinuxでは、SELinuxが原因でNginxがネットワーク接続を拒否されることが多々あります。

以下のコマンドを実行して、Nginxにネットワーク接続権限を許可してみてください。

Bash
sudo setsebool -P httpd_can_network_connect 1

これを実行した瞬間に502が治るケースは非常に多いです!

4. よくある原因と即効解決パターン3選

フローチャートのポイントを押さえたところで、現場で特に頻出する「あるある」なハマりパターンとその即効解決策を3つご紹介します。

パターン1:バックエンド(PHP-FPM / Node.js)が落ちている・起動していない

一番シンプルですが、一番多いのがこのパターンです。デプロイ直後やメモリ不足(OOM killer)によってバックエンドのプロセスが落ちてしまっているケースです。

  • 解決策: まずはプロセスの再起動を行います。
Bash
# PHP-FPMの場合(For PHP-FPM)
sudo systemctl restart php-fpm

# Node.js(PM2)の場合(For Node.js (when using PM2))
pm2 restart all

再起動してもすぐ落ちてしまう場合は、バックエンド側(/var/log/php-fpm/error.log や Node.jsのログ)を確認して、アプリ本体のエラーを解消しましょう。

パターン2:ソケットファイルのパーミッション・所有権エラー

NginxとPHP-FPMなどを「Unixドメインソケット(.sockファイル)」で通信させている場合によく起きる罠です。

ソケットファイルは存在するのに、Nginxを実行しているユーザー(nginxwww-data)に読み書き権限がないため、通信が拒否されてしまいます。

  • 解決策: PHP-FPMのpool設定ファイル(/etc/php-fpm.d/www.conf など)を開き、ソケットファイルの所有者設定を確認します。
INI
listen.owner = nginx
listen.group = nginx
listen.mode = 0660

設定変更後は sudo systemctl restart php-fpm を実行して反映させます。

パターン3:タイムアウト(処理に時間がかかりすぎている)

バックエンド側の処理(重いDBクエリや外部API通信など)に時間がかかりすぎ、Nginx側の応答待ち時間を超えてしまった場合も502(または504 Gateway Timeout)が発生します。

  • 解決策: Nginxの location ブロック内にタイムアウト時間を延長する設定を追加します。
Nginx
location / {
    proxy_pass http://127.0.0.1:3000;

    # タイムアウトを60秒から300秒(5分)に延長
    # Extend timeout from 60 seconds to 300 seconds (5 minutes)
    proxy_connect_timeout 300s;
    proxy_send_timeout    300s;
    proxy_read_timeout    300s;
}

設定追加後は sudo nginx -t で構文チェックを行い、sudo systemctl reload nginx で反映させましょう。

5. 【発展】502エラー検知時にX(旧Twitter)へ自動通知する仕組み

サーバーの障害や502エラーは、いつ何時発生するか分かりません。ユーザーからの指摘で初めて気づく…という事態を防ぐために、エラー検出時にX(旧Twitter)へ自動で通知を飛ばす仕組みを作っておくと安心です。

構成のイメージ

Nginxのエラーログを定期的に監視(あるいはcURL等でヘルスチェック)し、HTTPステータスコード 502 を検知した瞬間に、シェルスクリプトから X API v2 を叩いて通知ポストを送信します。

ステップ1:X APIのベアラートークン(またはOAuth 1.0a)を準備

まずは X Developer Portal でアプリを作成し、APIを使用するためのアクセスキー(API Key, API Key Secret, Access Token, Access Token Secret)を取得しておきます。
X Developer Account(開発者アカウント)の作り方は以下の記事で解説しています。

手動だと動くのにCronだと失敗する…の原因9割はコレ!『環境変数とパスの罠』を完全攻略
手動実行だと動くスクリプトがCronで失敗する原因の9割は、Cron特有の「ある初期設定」の差にあります。本記事では、初心者が100%ハマる「Cron静かな失敗の罠」の仕組みを解明!一発で確実に動作させる記述法から、エラー時の自動通知設定までまとめました。

ステップ2:502検知&X自動通知スクリプトを作成

以下は、Webサイトのヘルスチェックを行い、502エラーを検知したらXに投稿するシンプルなBashスクリプト例です。

Bash
#!/bin/bash

# 監視対象のURL
TARGET_URL="https://your-domain.com"
# HTTPステータスコードのみを取得
STATUS_CODE=$(curl -s -o /dev/null -w "%{http_code}" "$TARGET_URL")

# X API設定(Pythonスクリプト経由で送信するのが最も確実です)
if [ "$STATUS_CODE" -eq 502 ]; then
    echo "502 Bad Gateway detected! Sending notification to X..."
    
    # Pythonのtweepy等を使った通知スクリプトを呼び出す例
    python3 /path/to/send_x_alert.py "【障害アラート】$TARGET_URL で 502 Bad Gateway が発生しました!ログを確認してください。"
fi
Bash
#!/bin/bash

# Target URL to monitor
TARGET_URL="https://your-domain.com"
# Retrieve HTTP status code only
STATUS_CODE=$(curl -s -o /dev/null -w "%{http_code}" "$TARGET_URL")

# X (Twitter) API Settings (Sending via Python script is the most reliable approach)
if [ "$STATUS_CODE" -eq 502 ]; then
    echo "502 Bad Gateway detected! Sending notification to X..."
    
    # Example: Calling a notification script using Python's tweepy, etc.
    python3 /path/to/send_x_alert.py "[Incident Alert] 502 Bad Gateway detected on $TARGET_URL! Please check the system logs."
fi

送信用のPythonスクリプト(send_x_alert.py)例:

Python
import sys
import tweepy

# X API Credentials
API_KEY = "YOUR_API_KEY"
API_SECRET = "YOUR_API_SECRET"
ACCESS_TOKEN = "YOUR_ACCESS_TOKEN"
ACCESS_TOKEN_SECRET = "YOUR_ACCESS_TOKEN_SECRET"

# クライアントの初期化 (API v2)(Client initialization (API v2))
client = tweepy.Client(
    consumer_key=API_KEY,
    consumer_secret=API_SECRET,
    access_token=ACCESS_TOKEN,
    access_token_secret=ACCESS_TOKEN_SECRET
)

message = sys.argv[1]
client.create_tweet(text=message)

ステップ3:Cronで定期実行

作成したスクリプトをCronに登録し、5分おきなどに自動実行させます。

Bash
*/5 * * * * /bin/bash /path/to/check_502.sh >/dev/null 2>&1

これで、万が一サーバーが502エラーで沈んだ際も、スマホのXアプリに通知が届くため、迅速に一次対応へ向かうことができます!

6. まとめ:焦らず「エラーログ」から辿れば必ず直る!

Webサーバー運用で遭遇すると焦りがちな「502 Bad Gateway」ですが、原因のほとんどは「Nginxとバックエンド(アプリ)の間の通信不通」に集約されます。
あらためて、原因特定のための4ステップをおさらいしておきましょう。

  • STEP 1: まずは /var/log/nginx/error.log でエラーの直接原因を確認する
  • STEP 2: PHP-FPMやNode.jsなどのバックエンドプロセスが生きているか確認する
  • STEP 3: Nginxとアプリをつなぐポート番号やソケット(.sock)のパス・権限を照合する
  • STEP 4: ファイアウォールやSELinuxなどのセキュリティ設定をチェックする

闇雲に設定ファイルを書き換えてしまうと、かえって事態が複雑化してしまうこともあります。
まずは落ち着いてNginxのエラーログを見ることからスタートし、本記事のフローチャートに沿って1つずつ確認を進めてみてください。

トラブルシューティングの知識を身につけ、502エラーをサクッと撃退していきましょう!

コメント

タイトルとURLをコピーしました