この記事について
この記事は、生成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へ直接到達できる構成を避けるよう警告しています。
どの層が原因かを分ける
| 確認する層 | 読むもの | 分かること | これだけでは分からないこと |
|---|---|---|---|
| systemd | PHP-FPMのservice状態 | プロセス管理上の起動・失敗 | Nginxから到達できるか |
| PHP-FPM pool | listen、ソケット権限 | FPMが待ち受ける予定の先 | 実際に待ち受けているか |
| OSのソケット | ssの待受一覧 | Unix socket/TCPの待受 | Nginx設定と一致するか |
| Nginx | fastcgi_pass | Nginxが接続する予定の先 | 接続・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 denied | Unix 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ポートを外部へ開くこと、原因を記録せず再起動を繰り返すことは避けます。
公式情報・一次情報
PHP Manual — FastCGI Process Manager:FPMの役割、pool、FastCGIの安全性。
PHP Manual — FPM configuration:
listen、Unix socket権限、TCPアクセス制御。Nginx — FastCGI module:
fastcgi_pass、fastcgi_param、タイムアウト。Nginx — Command-line parameters:
-tと-Tの違い。systemd — systemctl:サービス状態の読み取り。
systemd — journalctl:サービス別ログの確認。
資料確認日:2026年10月10日。上記は随時更新される公式リファレンスであり、記事中で未確認の「資料公開日」は付けていません。
