【入門】 Nginx + PHP-FPM の仕組み
本記事では、PHP-FPM を初めて学ぶ方に向けて、Nginxとの連携や設定の基本を解説します🚀
PHP-FPMとは? 🤔
PHP-FPM(FastCGI Process Manager)は、PHPの処理を最適化するためのプロセスマネージャーです。Nginx は PHP を直接処理できないため、PHP-FPM が FastCGI というプロトコルを利用して Nginx と PHP の橋渡しを行います。
⚡ FastCGIとは?
FastCGI とは、Webサーバーとアプリケーションの間で高速な通信を実現するプロトコルです。従来のCGIとは異なり、リクエストごとにプロセスを作成・破棄するのではなく、プロセスを維持しながら複数のリクエストを効率的に処理できます。
以下のような構成でNginxとPHP-FPMが連携し、リクエストが処理されます。
🗣️ シーケンス図の説明
- クライアント(ブラウザやAPIリクエスト)がNginxにHTTPリクエストを送信
- Nginx がリクエストを受け取り、静的ファイル(HTML, CSS, JSなど)はそのまま返す
- PHPスクリプトの場合、NginxはFastCGIを通じてPHP-FPMにリクエストを転送
- PHP-FPMがスクリプトを実行し、結果をNginxに返す
- Nginx がPHPの実行結果をクライアントにレスポンスとして返す
PHP-FPMのプールとは? 🏊♂️
PHP-FPM は「プール」という単位でプロセスを管理します。プールごとに同時接続数やプロセスの数を指定でき、プロセスやソケットは別のものを使います。使用するPHPアプリケーションごとにPHP-FPMのプールを作り、使用する資源を分けるといった使い方ができます🙆♀️
🏊♀️ プールの主な構成要素
- マスター・プロセス:設定を読み込み、ワーカープロセスを管理する
- ワーカープロセス:実際にPHPスクリプトを処理する
- リスナー(ソケット):Webサーバーとの通信を管理する
デフォルトでは www
という名前のプールが作成されますが、用途に応じて追加・変更できます。
PHP-FPM の設定ファイル 🛠
Nginxをインストール後、PHP と PHP-FPM を導入(yum install php php-fpm
)すると、以下のような設定ファイルが作成されます。
/etc # 設定ファイルのディレクトリ
├── php.ini # PHP の基本的な設定を記述するファイル
├── php-fpm.conf # PHP-FPM のメイン設定ファイル
├── php-fpm.d/
│ ├── www.conf # プール設定ファイル
動作環境のOSは、 Amazon Linux 2023 です。
参考:🔗 2024年版 - AWSのEC2にPHP+Nginx+phpMyAdminの環境を構築する
1️⃣ php-fpm.conf の概要
php-fpm.conf
は、PHP-FPM のメインの設定ファイルです。PHP-FPM の動作設定などが含まれます。
以下は PHP-FPM の php-fpm.conf
の初期設定値です。(初期設定でコメントアウトされているコードは省略しています。)
include=/etc/php-fpm.d/*.conf
[global]
pid = /run/php-fpm/php-fpm.pid # プロセス ID を格納するファイルのパス
error_log = /var/log/php-fpm/error.log # エラーログファイルのパス
daemonize = yes # デーモンとして実行するかどうか
2️⃣ /etc/php-fpm.d/*.conf の概要
このディレクトリには、PHP-FPM の設定を分割して管理するための設定ファイルが「プール」単位で格納されています。デフォルトでは、www.conf
というプール設定ファイルが生成されています。
以下は www.conf
ファイルの設定例です。(初期値を一部変更しています)
[www] # プールの名前
user = nginx # プールを実行するユーザー名
group = nginx # プールを実行するグループ名
listen = /run/php-fpm/php-fpm.sock # リッスンソケットのパス
listen.owner = nginx # ソケットファイルの所有者
listen.group = nginx # ソケットファイルのグループ
listen.allowed_clients = 127.0.0.1 # アクセスを許可するクライアントのIPアドレス (localhost のみ許可)
pm = dynamic # プロセスマネージャーの動作モード (動的にプロセス数を調整)
pm.max_children = 50 # 最大ワーカープロセス数
pm.start_servers = 5 # 起動時のワーカープロセス数
pm.min_spare_servers = 5 # 最小アイドルワーカープロセス数
pm.max_spare_servers = 35 # 最大アイドルワーカープロセス数
pm.status_path = /status # PHP-FPM のステータス情報を取得できるパス
slowlog = /var/log/php-fpm/www-slow.log # スローリクエストのログファイルパス
php_admin_value[error_log] = /var/log/php-fpm/www-error.log # PHP エラーログファイルパス
php_admin_flag[log_errors] = on # PHP エラーログを有効にする
php_value[session.save_handler] = files # セッションハンドラーを files に設定 (ファイルベースセッション)
php_value[session.save_path] = /var/lib/php/session # セッションファイルの保存パス
php_value[soap.wsdl_cache_dir] = /var/lib/php/wsdlcache # SOAP WSDL キャッシュディレクトリ
📌 ポイント
- プールを実行する
user
とgroup
の値はnginx
を設定しています。- PHP-FPM の プロセスは Nginx と同じユーザーの権限で動作します。PHPプログラムとNginx の権限の違いによるトラブルを避けるために、Nginx が使用するユーザーと同じユーザーで PHP-FPM を実行することが一般的です。
-
listen
では Nginx が PHP-FPM と通信するためのソケットファイルのパスを指定します。- デフォルトのパスを変更する場合は、Nginxの設定ファイル (
nginx.conf
など) のfastcgi_pass
ディレクティブも合わせて変更する必要があります。
- デフォルトのパスを変更する場合は、Nginxの設定ファイル (
参考:🔗 php 公式 - php-fpm.conf と、プール設定ファイル
Nginxとの連携 🔗
PHP-FPM を Nginx と連携させることで、Nginx を Webサーバー として PHP の処理を PHP-FPM に任せることができます。
以下は PHP-FPM を Nginx と連携するための設定を Nginx の設定ファイル nginx.conf
で記述する例です。
nginx.conf
の設定例
📝 server {
listen 80;
server_name example.com;
root /var/www/html;
index index.php index.html index.htm;
location / {
try_files $uri $uri/ =404;
}
location ~ \.php$ {
include fastcgi_params; # FastCGIの基本設定を読み込む
fastcgi_pass unix:/run/php-fpm/php-fpm.sock; # PHP-FPMと接続
fastcgi_index index.php; # デフォルトのPHPスクリプト
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; # 実行するPHPファイルを指定
}
}
🗣️ 各ディレクティブの解説
-
try_files
- 引数を前から順番にファイルがあるかをどうかを調べていき、なければ最後の引数の処理をします。(この場合404 エラーを返す)
-
$uri
はアクセスされた URL のパス部分を表します。
-
include fastcgi_params
- FastCGI の環境変数を設定するファイル (
/etc/nginx/fastcgi_params
) を読み込みます。 - 次の
fastcgi_param
は、fastcgi_params
に含まれていない変数を追加するために使用されます。
- FastCGI の環境変数を設定するファイル (
-
fastcgi_param
- Nginx が PHP-FPM にリクエストを渡す際に、FastCGI の環境変数を設定するために使用されます。
-
fastcgi_pass
- FastCGI サーバー(PHP-FPM)のアドレスを指定します。
- ここでは、PHP-FPMの www プールの設定で指定したアドレス
/run/php-fpm/php-fpm.sock
を指定しています。
PHP の PATH_INFO について ✍️
PHP プログラムでは PATH_INFO
という変数がよく利用されます。
PATH_INFO
とは、PHP スクリプトのファイル名の後に追加情報を付与するための仕組みです。
例えば、以下の URL の extra/info
の部分が PATH_INFO
になります。
https://example.com/index.php/extra/info
しかし、nginx.conf
の location ~ \.php$
では、このようなパスを処理できません。
PATH_INFO
に対応する場合は、少し複雑な正規表現で設定を追加する必要があります。
PATH_INFO
を処理する設定
📝 server {
location ~ [^/]\.php(/|$) {
fastcgi_split_path_info ^(.+\.php)(/.+)$;
if (!-e $document_root$fastcgi_script_name) {
return 404;
}
…
fastcgi_param PATH_INFO $fastcgi_path_info;
…
}
}
🗣️ 各ディレクティブの解説
-
location ~ [^/]\.php(/|$)
-
\.php
の前の[^/]
は、/dir/.php
のようにドットで始まるファイルを除外するための表現です。 - 末尾の
(/|$)
は、.php
で終わるパスまたは/
が続くパスのみを対象にします。
-
-
fastcgi_split_path_info
- スクリプトファイル名と
PATH_INFO
を分割し、それぞれ$fastcgi_script_name
と$fastcgi_path_info
に格納します。 - 例:
/dir/file.php/arg1
→$fastcgi_script_name = /dir/file.php
,$fastcgi_path_info = /arg1
- これらの変数を
fastcgi_param
ディレクティブで FastCGI に渡します。
- スクリプトファイル名と
-
if (!-e $document_root$fastcgi_script_name)
-
fastcgi_split_path_info
で分割されたファイル名のファイルが存在しない場合に「404 (Not Found)」を返すように指定しています。
-
まとめ 🎯
✅ Nginx と PHP-FPM の連携により、PHP アプリの高速処理が可能になる🚀
✅ 設定ファイル (nginx.conf
) を適切に記述し、リクエストの処理をスムーズに🎛️
業務で PHP アプリケーションの設定をリファクタリングする中で学んだ内容をまとめました💻
もしご指摘やアドバイスがありましたら、コメントいただけますと幸いです📝
以上、えみり〜でした|ωΦ)ฅ
Discussion