はじめに
Nginx で PHP-FPM を設定するとき、なんとなく触っていたのですが、改めてどういうものか理解していこうと思い、基本的な設定を見直しながら復習がてら記載しました。
PHP-FPM ?
FastCGI は、Open Marketという会社によって1990年代中頃に開発されたもののようで、仕様は公開されています。元のページはなくなっているようで、アーカイブ状態で残っているようでした。
「1つのリクエスト毎に1つのプロセス」という形では、実装は簡単であるものの、OSによるプロセス起動停止に伴ってのオーバーヘッドが無視できなくなるであろう問題を解決するために、永続的なプロセスを使用して一連のリクエストを処理する形としているようです。Webサーバーのプロセスではなく、FastCGIのサーバープロセスが別途で起動して処理するようです。
Nginx と組み合わせて利用する場合の構成イメージは下記のような感じかと思います。Nginx と PHP-FPM は同一サーバー上でも別々のサーバー上でも実行できます。 Nginxがリクエストを受け付けたら、必要な情報と共に php-fpm プロセスへリクエストを流して、php-fpm が php プログラムを実行して必要な情報を Nginx へ返し、Nginxがクライアントへレスポンスを返す、といった流れかと思います。

Nginx + PHP-FPM
Nginx と PHP-FPM を連携する設定を見ていきます。
PHP の公式ページだと、デフォルトは以下のようなものであると記載されています。
location / { root html; index index.php index.html index.htm; } location ~* \.php$ { fastcgi_index index.php; fastcgi_pass 127.0.0.1:9000; include fastcgi_params; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; fastcgi_param SCRIPT_NAME $fastcgi_script_name; }
location / { ... } ディレクティブ
最初の location ディレクティブでは、/ の場合に、インデックスファイルが index.php , index.html, index.htm の順に利用できることを示してます。/ でリクエストされた場合、内部的に /index.php として処理される形になります。index.php がなければ index.htmlを、それがなければ index.htm を利用する形になります。 すべてのパスは /path/to/xxx.html といった/ で始まるため、他のlocationディレクティブのパスの条件に一致したもの以外はこのlocationディレクティブが適応されます。
location ~* .php$ { ... } ディレクティブ
次の location ディレクティブでは、リクエストの内容が .php にマッチする場合の処理が記述されています。
fastcgi_indexは, 後述の$fastcgi_script_name変数の値の中に、スラッシュで終わるURIの後に追加されるファイル名を設定します。例えばfastcgi_index index.phpの場合/のリクエストならfastcgi_script_nameに/が入るため、これに inxex.php を加えて/index.phpに、/info/の場合はfastcgi_script_nameに/info/が入るため、これに/info/index.phpになります。fastcgi_passは, FastCGIサーバのアドレス、またはUnixドメインソケットを指定します。NginxとPHP-FPMが同一サーバー上で実行されている場合はUnixドメインソケットで通信した方が処理は速いと思います。NginxとPHP-FPMが別サーバーである場合はTCPを利用することになると思います。Unixドメインソケットを利用する場合は PHP-FPM がUnixドメインソケットを使うように設定する必要があります。include fastcgi_paramsは, Nginx のfastcgi_paramsファイル内にあるパラメーターを読み込みます。 Ubuntu だと/etc/nginx/fastcgi_paramsにあると思います。ここで読み込まれたパラメーターが php-fpm へ渡されます。これらの渡された値は PHP の$_SERVER変数で参照できます。fastcgi_paramは,include fastcgi_paramsで読み込んだ値に追加・上書きでパラメーターを設定します。fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;では、PHPスクリプトファイルが配置されているディレクトリフルパスが設定されます。$document_rootは、Nginx の server ブロック内に設定されている root ディレクティブの値になります。 以下では/var/www/nginx/appとなっていると仮定します。$fastcgi_script_nameは、リクエストURI、または、もしURIがスラッシュで終わる場合は,fastcgi_indexディレクティブで設定されたindexファイルを追加したリクエストURI になります。例えば、リクエストがhttps://example.com/info/test.phpの場合は$fastcgi_script_nameに/info/test.phpが入るため、/var/www/nginx/app/info/test.phpとして処理される形になります。https://example.com/の場合はfastcgi_indexの値であるindex.php付与されて/index.phpが設定されるため、SCRIPT_FILENAMEは/var/www/nginx/app/index.phpとなります。
fastcgi_param SCRIPT_NAME $fastcgi_script_name;はリクエストファイルのパスを含めた値が設定されます。
まとめ
Nginx で PHP-FPM を設定するときの Config をあまり理解してないまま触っていたので、基本的な設定項目について調べて記載しました。
参考
- NGINX Documentation
- Module ngx_http_fastcgi_module
- Module ngx_http_fastcgi_module
- https://mogile.web.fc2.com/nginx_wiki/start/topics/tutorials/config_pitfalls/
- https://mogile.web.fc2.com/nginx_wiki/start/topics/examples/phpfcgi/
- PHP: $_SERVER - Manual
- PHP: Nginx 1.4.x (Unix システム用) - Manual
- FastCGI.com Archives
- https://www.ietf.org/rfc/rfc3875
- nginx連載5回目: nginxの設定、その3 - locationディレクティブ - インフラエンジニアway - Powered by HEARTBEATS