Ubuntu Server 22.04 ガイド
WEB 02 / 05

PHP-FPMの実行環境を作る

Nginxを選んだ場合のPHP連携手順です。PHP-FPMを呼び出し、PHPの実行と確認用ファイルの削除を確かめます。

Apache・Caddyを選んだ場合は各サーバーのページのPHP連携を使います。このページのNginx設定ファイルは適用しません。

01 / PHPの版と構成を確認する

NginxでWebページを配信する手順を完了し、/var/www/server-guide/publicの静的ページが別端末から表示できる状態を前提にします。以降はサーバー上の一般管理者で実行します。物理機・VMで手順は共通です。

この章はUbuntu 22.04公式リポジトリのPHP 8.1とPHP-FPMを使います。上流のPHP 8.1は保守を終了しています。Ubuntu 22.04側のパッケージ保守は別なので、Ubuntuの更新提供範囲とアプリのPHP対応を確認してください。PHP 8.1を最新版として導入する手順ではありません。より新しいPHPが必要なアプリは、対応するUbuntu LTS等の構成を選び、この手順へ異なる版やPPAを混ぜないでください。

NginxがHTTPを受け、PHP-FPMへUnixソケット経由で処理を渡します。PHP-FPMのTCPポートを外部公開したり、UFWに9000番の許可を追加したりする必要はありません。

sudo nginx -t
systemctl is-active nginx
sudo ls -l /etc/nginx/sites-enabled/
apt-cache policy php8.1-fpm

02 / PHP-FPMと拡張を導入する

sudo apt-get update && sudo apt-get install php8.1-fpm php8.1-cli php8.1-mysql php8.1-curl php8.1-gd php8.1-mbstring php8.1-xml php8.1-zip
sudo systemctl enable --now php8.1-fpm
php -v
php -m
systemctl is-active php8.1-fpm
systemctl is-enabled php8.1-fpm
sudo ls -l /run/php/php8.1-fpm.sock

FPMがactive・enabledで、/run/php/php8.1-fpm.sockが存在することを確認します。CLIとWeb側は別の設定を使うため、php -vだけではWebでのPHP実行成功になりません。MySQL・画像・文字列・XML等の拡張は後のアプリ構築でも使用します。

03 / NginxとFPMを連携する

Nginxの対象サイトをバックアップし、保存先を控えます。server-guide以外の既存サイトを使っている場合は、そのまま上書きせず構成を見直してください。

BACKUP="$(sudo mktemp -d /root/server-guide-php.XXXXXX)" &&
sudo cp -a /etc/nginx/sites-available/server-guide "$BACKUP/site.conf"
printf '保存先: %s
' "$BACKUP"

前章の専用サイト設定を次の内容へ変更します。location ~ \.php$内でUbuntu付属のFastCGI設定を読み込み、FPMソケットへ渡します。このスニペットは存在しないPHPスクリプトをtry_filesで404にする構成です。ファイルの存在確認を外したり、任意のパスをFPMへ渡したりしないでください。

sudo tee /etc/nginx/sites-available/server-guide >/dev/null <<'EOF'
server {
    listen 80 default_server;
    server_name _;
    root /var/www/server-guide/public;
    index index.php index.html;

    location / {
        try_files $uri $uri/ =404;
    }
    location ~ /\. {
        deny all;
    }
    location ~ \.php$ {
        include snippets/fastcgi-php.conf;
        fastcgi_pass unix:/run/php/php8.1-fpm.sock;
    }
}
EOF
sudo nginx -t && sudo systemctl reload nginx

構文検査と再読み込みが成功してから、次の一時PHPファイルを作ります。ソケットのパスが実在するものと一致することも確認してください。設定変更が失敗したままPHPファイルを公開領域へ置きません。

04 / PHP実行と削除後の404を確認する

既存ファイルを上書きしないよう検査して、バージョンだけを返す一時ファイルを作ります。phpinfo()は環境情報を広く表示するため使用しません。

sudo test ! -e /var/www/server-guide/public/health.php &&
sudo tee /var/www/server-guide/public/health.php >/dev/null <<'PHP'
<?php
header('Content-Type: text/plain; charset=UTF-8');
echo 'PHP ' . PHP_VERSION . "\n";
PHP
sudo chown root:root /var/www/server-guide/public/health.php
sudo chmod 644 /var/www/server-guide/public/health.php
curl --fail --show-error http://127.0.0.1/health.php

PHP 8.1...のような実行結果が返り、<?phpから始まるソースコードが返らないことを確認します。別端末でもhttp://SERVER_IP/health.phpを開いて確認します。ソースが見えたりファイルをダウンロードする動作になったら、公開を止め、NginxのPHP用locationと読み込まれているサイトを調べてください。

確認後は一時ファイルを削除します。削除後のURLと、初めから存在しないPHPファイルのURLがどちらも404になることを確認します。以下の確認はHTTPステータス表示用なので、404でもcurl自体は正常終了する場合があります。

sudo rm /var/www/server-guide/public/health.php
curl -sS -o /dev/null -w '%{http_code}\n' http://127.0.0.1/health.php
curl -sS -o /dev/null -w '%{http_code}\n' http://127.0.0.1/server-guide-missing.php

server-guide-missing.phpが実在しないことも確認してください。一時ファイルは運用サーバーに残さず、ログイン・個人情報を扱うアプリを設置する前に次章のHTTPSを整えます。

参考:動作確認と撮影条件

Ubuntu Server 22.04.5の実VMでPHP 8.1.2-1ubuntu2.28を使用しました。Unixソケット経由でHTTP 200とPHPの実行結果を確認し、ソースが本文に出ないことも確認しています。FPM停止時は502、再起動後は復旧しました。確認用ファイルの削除後と存在しないPHPは404でした。接続は別クライアントからのNAT転送と管理用SSHトンネルで、公開インターネット・IPv6は未検証です。

PHP-FPMの有効状態とPHP実行の確認画面
Ubuntu Server 22.04の検証用VMの実画面。読者のアドレスやバージョンは環境により異なります。

05 / 502の切り分けと保守

502 Bad Gatewayは、まずFPMの起動状態、Unixソケットのパスと権限、Nginx側のfastcgi_passを確認します。ソケットを777へ変更して解決しようとせず、サービスと標準の所有者・グループ設定を照合してください。

systemctl status php8.1-fpm --no-pager
sudo journalctl -u php8.1-fpm -b --no-pager
sudo tail -n 50 /var/log/nginx/error.log
sudo /usr/sbin/php-fpm8.1 -t
sudo nginx -t

エラー表示を本番画面へ常時出さず、PHPの設定変更は/etc/php/8.1/fpm/php.ini等の対象を確認して行います。CLI側のphp.ini変更だけではFPMへ反映されません。必要な変更をバックアップし、FPMの構文検査後に再読み込みします。

この章だけを戻す場合は一時PHPファイルを削除し、保存したsite.confを対象サイトへ復元してsudo nginx -t && sudo systemctl reload nginxを実行します。前章の静的設定ではPHP URLを404にするため、PHPソースを配信しません。アプリ導入後はファイル・DBとの整合を含む別の復旧計画が必要です。

WebでPHPが動作し、一時ファイルの削除後が404になったら、ドメインとHTTPSへ進みます。参考:PHP-FPM公式マニュアル、PHPの保守対象バージョン。