dshimizu/blog

Something I Learned.

Nginx での PHP-FPM 用の設定方法についておさらいした

はじめに

Nginx で PHP-FPM を設定するとき、なんとなく触っていたのですが、改めてどういうものか理解していこうと思い、基本的な設定を見直しながら復習がてら記載しました。

PHP-FPM って?

PHP における FastCGI 実装とのことです。

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 ディレクティブでは、/ の場合に、インデックスファイルが index.php , index.html, index.htm の順に利用できることを示してます。/ でリクエストされた場合、内部的に /index.php として処理される形になります。index.php がなければ index.htmlを、それがなければ index.htm を利用する形になります。 すべてのパスは /path/to/xxx.html といった/ で始まるため、他のlocationディレクティブのパスの条件に一致したもの以外はこのlocationディレクティブが適応されます。

次の location ディレクティブでは、リクエストの内容が .php にマッチする場合の処理が記述されています。

fastcgi_index$fastcgi_script_name 変数の値の中のスラッシュで終わるURIの後に追加されるファイル名を設定します。例えば / のリクエストの場合は /index.php に、/info/ の場合は /info/index.php になります。

fastcgi_passFastCGIサーバのアドレス、または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_paraminclude fastcgi_params で読み込んだ値に追加・上書きでパラメーターを設定します。 fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; では、スクリプトファイルのディレクトリフルパスが設定されます。具体的には、 $document_root は、Nginx の server ブロック内に設定されている root ディレクティブの値になります。$fastcgi_script_name では、リクエスURI、または、もしURIがスラッシュで終わる場合は fastcgi_index ディレクティブで設定されたindexファイルを追加したリクエスURI になります。例えば、リクエストがhttps://example.com/info/test.php の場合は $fastcgi_script_name/info/test/php が、https://example.com/ の場合は fastcgi_index の値である index.php 付与されて /index.php が設定されます。 fastcgi_param SCRIPT_NAME $fastcgi_script_name; はリクエストファイルのパスを含めた値が設定されます。

まとめ

Nginx で PHP-FPM を設定するとき、なんとなく触っていたので、基本的な設定を見直しながら復習がてら記載しました。

参考