NginxでPHPだけ502になるときの確認順 ― PHP-FPMのservice・socket・fastcgi_passを追う

Linux・CLI・DevOpsカテゴリを表すパンダのイラスト Linux・CLI・DevOps

この記事について
この記事は、生成AIを活用した自動生成フローで作成しています。PHP公式マニュアル、NginxのFastCGIモジュール仕様、systemdの操作資料を確認し、PHP-FPMのサービス・待受先・Nginx設定を順に照合する手順を整理しました。

検証ステータス:📘 公式仕様確認済み・対象Ubuntu実機未確認
情報確認日:2026年10月10日。コマンドは読み取り中心です。以下のログや画面表示は説明用の例であり、実際のサーバーで採取した結果ではありません。

NginxではHTMLを表示できるのに、PHPのページだけ502 Bad Gatewayになる場合、最初に確かめたいのはNginxが転送する先と、PHP-FPMが待ち受ける先が一致しているかです。PHP-FPMが停止している場合だけでなく、ソケットのパス違い、アクセス権限、応答の遅延などでも失敗します。502という数字だけでPHP-FPMの停止と決めつけず、通信の経路を分けて確認します。

PHPのリクエストはどこを通る?

PHP-FPMは、PHPプログラムを実行するためのFastCGIプロセスマネージャーです。FastCGIはWebサーバーからアプリケーション実行側へリクエストを渡す仕組みです。Nginxのfastcgi_passは転送先を指定し、PHP-FPMのpool設定にあるlistenは受信先を指定します。

flowchart LR
    A["ブラウザー"] -->|HTTP/HTTPS| B["Nginx"]
    B -->|"fastcgi_pass"| C["Unix socket または TCP"]
    C -->|"listen"| D["PHP-FPM pool"]
    D --> E["PHPスクリプト"]

NginxとPHP-FPMが同じマシンなら、Unixドメインソケット(.sockというパスを使うローカル通信)がよく使われます。別ホスト・コンテナ間ならTCP接続を使う構成もあります。PHP公式資料は、信頼できないネットワークからFastCGIへ直接到達できる構成を避けるよう警告しています。

どの層が原因かを分ける

確認する層読むもの分かることこれだけでは分からないこと
systemdPHP-FPMのservice状態プロセス管理上の起動・失敗Nginxから到達できるか
PHP-FPM poollisten、ソケット権限FPMが待ち受ける予定の先実際に待ち受けているか
OSのソケットssの待受一覧Unix socket/TCPの待受Nginx設定と一致するか
Nginxfastcgi_passNginxが接続する予定の先接続・PHP実行が成功したか
ログNginx/FPMの直近エラー失敗時刻・エラー種別根本原因のすべて

たとえば、serviceがactiveでも、Nginxが古いバージョンのソケットを指していればPHPは表示されません。逆にfastcgi_passの文字列が正しくても、PHP-FPMが起動していなければ接続できません。

1. PHP-FPMのservice名と状態を確認する

Ubuntuでは、PHPのバージョンによってphp8.3-fpm.serviceのような名前が付く場合があります。8.3は例なので、最初からその名前だと決めず、一覧で確認します。

# インストール済み・認識済みのPHP-FPMサービス候補を表示

systemctl list-units --type=service --all 'php*-fpm.service' --no-pager

# 上の一覧で確認できたサービス名を指定する(8.3は例)

systemctl status php8.3-fpm.service --no-pager
systemctl is-active php8.3-fpm.service

# 同じサービスの直近ログを現在の起動に限定して読む

journalctl -u php8.3-fpm.service -b -n 40 --no-pager

activeならsystemd上は起動状態です。failedやinactiveなら、再起動の前にjournalの失敗理由を確認します。Unit ... could not be foundなら、サービス名やインストール構成を再確認してください。アクセス権限によってjournalの一部が見えない場合もあります。

ここを見る: Active、Main PID、Result、起動失敗の時刻。単に「enabledだから動いている」とは判断しません。enabledは自動起動設定、activeは現在の稼働状態で、意味が違います。

2. PHP-FPM poolのlistenを確認する

PHP-FPMはpoolごとに待受先を設定できます。Ubuntuの一般的なパッケージ配置では/etc/php/以下にバージョン別の設定が置かれますが、ディストリビューションや導入方法で異なります。

# 読み取り可能なpool設定からlistenと権限項目を探す


# 何も出ない場合はパス違い・権限不足・未設定を区別する

grep -HnE '^[[:space:]]*listen(\.(owner|group|mode))?[[:space:]]*=' \
  /etc/php/*/fpm/pool.d/*.conf

たとえば、次のように表示されたとします。

listen = /run/php/php8.3-fpm.sock
listen.owner = www-data
listen.group = www-data
listen.mode = 0660

これは設定例です。listenは受信先、listen.owner・listen.group・listen.modeはUnix socketの権限を制御します。実際の値は環境で変わります。ファイルが読めないときに権限を広げたり、安易にchmod 777を使ったりしないでください。

PHP公式のFPM設定資料では、Unix socketの所有者・グループ・モードと、TCP待受時のアクセス制御を別々に説明しています。

3. ソケットが実際に待ち受けているかを見る

設定ファイルにlistenが書かれていても、実際の待受が存在するとは限りません。

# Unix domain socketの待受を表示(読み取り専用)

ss -xl

# TCPで待ち受けている構成の場合はこちらを確認

ss -ltn

ss -xlはUnix socketの一覧、ss -ltnは待受TCPの一覧です。表示に含まれる実パス・ポート・プロセス構成は公開しないでください。ssがない、または権限不足で一部が見えない場合は、「待受なし」と断定しないことも重要です。

ソケットファイルが見つかるだけでは、Nginxから接続できる保証はありません。次のfastcgi_passと合わせて判定します。

4. Nginxのfastcgi_passと照合する

NginxのFastCGIモジュールは、Unix socketを使う場合、次のようにunix:を付けて転送先を指定します。

# 例:Nginx側

fastcgi_pass unix:/run/php/php8.3-fpm.sock;

対応するPHP-FPM側の設定例は次です。

; 例:PHP-FPM pool側
listen = /run/php/php8.3-fpm.sock

この組み合わせなら、少なくとも文字列としての接続先は対応しています。一方、Nginxだけphp8.2-fpm.sockを指していたら、サービスが起動していても接続先がずれています。

Nginx設定の確認では、nginx -tが構文や参照ファイルを検査し、nginx -Tは設定全体の内容も表示します。

# 設定変更やreloadをせずに構文検査

nginx -t

# 必要なときだけ、端末上で有効設定のFastCGI関連行を確認


# -Tは設定全体を出力するため、実行結果を外部へ貼らない

nginx -T 2>&1 | grep -nE 'fastcgi_pass|SCRIPT_FILENAME'

nginx -Tは秘密値・ホスト名・内部パスを含む設定全体を出力し得ます。パイプで一部を絞っても、共有前の目視マスクは必須です。権限不足によるnginx -tの失敗と、実際のNginxサービスの障害も混同しないでください。仕様はNginxのコマンドオプションで確認できます。

TCP構成ならfastcgi_pass 127.0.0.1:9000;のようにポートで指定する例もあります。ただしFastCGIを外部公開するのは危険です。この記事は設定変更を案内するものではなく、既存の通信経路を安全に観察する手順です。

5. 502のログを「接続失敗」と「応答失敗」に分ける

NginxとPHP-FPMのログを同じ時刻帯で比較します。

# Nginxのjournalが記録されている場合

journalctl -u nginx.service -b -n 60 --no-pager

# PHP-FPM側のログ(サービス名は実際のものに置き換える)

journalctl -u php8.3-fpm.service -b -n 60 --no-pager

次は典型的なメッセージの説明例であり、実サーバーの採取ログではありません。

ログの一部最初に疑う場所次の確認
No such file or directory指定したsocketパスが存在しないlistenとfastcgi_passのパス
Permission deniedUnix socketへのアクセス権限socketのowner/group/modeとNginx実行ユーザー
Connection refused転送先が接続を受け付けない待受・service状態・転送先
upstream timed out応答が期限内に届かないPHP処理時間、FPM poolの混雑、timeout設定

ログ文言だけで修正を決めず、対象のリクエスト・時刻・転送先をそろえて確認します。PHPのアプリケーション例外、SCRIPT_FILENAMEの誤設定、FPMのワーカー不足などは、socketのパスが合っていても別途調査が必要です。SCRIPT_FILENAMEは実行対象のPHPスクリプトのパスを渡すFastCGIパラメーターです。

自分の環境で試す前に:安全な確認用サンプル

GitHubのPHP-FPM経路確認サンプルには、サービス候補、poolのlisten、socket待受、NginxのFastCGI関連設定を読み取り中心で並べて見るシェルスクリプトがあります。実行前にコードを確認してください。出力には環境固有のパスが含まれる可能性があります。

# リポジトリを取得済みの場合の実行例

cd ubuntu/php-fpm-trace
bash ./check-php-fpm-path.sh

期待するのは「すべての項目が表示されること」ではなく、どの層まで確認でき、どこが一致しないかを判断できることです。権限不足や未インストールで表示できない項目があっても、他の層の観察は続けられます。実機未確認なので、ここで特定の出力値を実測結果として示しません。

1か所変えて理解する

本番の設定は触らず、紙やメモ上の次の2行を比べてください。

PHP-FPM: listen = /run/php/php8.3-fpm.sock
Nginx:   fastcgi_pass unix:/run/php/php8.3-fpm.sock;

Nginx側の8.3を8.2に変えると、見かけ上は小さな差でも、接続先は別のパスになります。この違いが分かれば、PHP-FPMを無条件に再起動するより前に、何を確認すべきかが明確になります。

運用時の注意と後始末

今回の確認コマンドは設定変更、reload、restartを行いません。後始末も原則不要です。ただしログや設定には秘密情報や内部構成が含まれる場合があります。AIや外部の相談先へ共有する際は、必要箇所だけ抜き出し、認証情報・実ドメイン・IP・パス・アカウント名をマスクしてください。

502の原因を特定した後も、変更内容・影響範囲・復旧方法を確認してから別工程で修正します。特にsocket権限を無制限に緩めること、FastCGIポートを外部へ開くこと、原因を記録せず再起動を繰り返すことは避けます。

公式情報・一次情報

資料確認日:2026年10月10日。上記は随時更新される公式リファレンスであり、記事中で未確認の「資料公開日」は付けていません。

GitHubサンプル

文書情報

記事タイトル
NginxでPHPだけ502になるときの確認順 ― PHP-FPMのservice・socket・fastcgi_passを追う
作成日
更新日
Source URL
https://papanda925.com/?p=18113

ライセンス: 本記事のうち、当サイトが権利を有する本文・自作図表は、特記なき限り CC BY 4.0 で利用できます。生成AIを活用して作成・編集した内容を含みます。コードについて、別途ライセンス表示またはリンク先GitHubリポジトリのライセンスがある場合は、その条件を優先します。引用・第三者資料・画像・商標等は本ライセンスの対象外です。 利用ポリシー

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