PHP-FPMとは | PHP-FPMのインストールと設定
PHP-FPMは、Webサーバーから渡されたPHPのリクエストを、あらかじめ起動しておいたワーカープロセスが受け取って処理するFastCGIのプロセスマネージャーです。Apacheが動いているAlmaLinux 9サーバーで、インストールの有無とサイトアカウントごとのプール・ソケットの設定を確認し、設定の検査と状態の確認まで実際の出力でまとめました。
Apacheはmod_phpでPHPを直接実行することもできますが、PHP-FPMに渡すとWebサーバーとPHPが分離されます。NginxはPHPを直接実行できないため、PHP-FPMのようなFastCGIプロセスに渡します。そのため、PHP-FPM 1つにApacheとNginxのどちらでも接続できます。下のプール設定とソケットの構造は、PHP-FPMとNginxを接続するときもそのまま当てはまります。
1️⃣ PHP-FPMとは:CGIとFastCGIの違い
CGI(Common Gateway Interface)は、Webサーバーが外部のプログラムを実行して動的なコンテンツを作る標準的な方式で、リクエストが来るたびにプログラムを新しく起動します。リクエストごとにプロセスを作って消すコストが積み重なり、アクセスが増えるほどサーバーの応答が遅くなります。
FastCGIは、このコストをなくすためにプログラムをあらかじめ起動しておき、リクエストを続けて処理する方式です。使うたびにパソコンの電源を入れて切るのと、電源を入れたままのパソコンをすぐ使うのとの違いです。PHP-FPM(FastCGI Process Manager)はPHPをFastCGIで動かすマネージャーで、PHP 5.3.3からPHPに含まれています。
PHP-FPMは、ワーカーの集まりであるプール(pool)ごとに決めた数のワーカーをあらかじめ起動しておき、Webサーバーがソケットで渡したリクエストを空いているワーカーが受け取って処理し、次のリクエストを待ちます。画像やCSSのような静的ファイルはWebサーバーが直接応答し、PHPファイルだけがPHP-FPMに渡されます。Webサーバーがソケットにリクエストを渡す方法だけが異なり、Apacheはmod_proxy_fcgiモジュールを、Nginxはfastcgi_passの設定を使います。
2️⃣ PHP-FPMのインストール:パッケージの確認とdnfでのインストール
RHEL系サーバーでdnfを使ってPHPをインストールしたなら、php-fpmパッケージも一緒にインストールされています。まずrpmでインストールされているかを確認します。PHPのインストール手順は Rocky Linux APMのインストールと同じです。
rpm -qa | grep php-fpmphp-fpm-8.3.36-1.module_php.8.3.el9.remi.x86_64出力が空ならインストールされていない状態なので、dnfでインストールします。
dnf -y install php-fpmインストールが終わったら、同じrpmコマンドでパッケージ名が表示されるかをもう一度確認します。
3️⃣ PHP-FPMの設定:www.confのプールとソケット、静的モードと動的モード
設定ファイルは、全体設定の[/etc/php-fpm.conf]とプール設定の[/etc/php-fpm.d/www.conf]の2つです。標準のプールwww.confで最初に見る行はlistenとpmで、インストール直後の値は次のとおりです。
grep -E '^(listen|pm) ' /etc/php-fpm.d/www.conflisten = /run/php-fpm/www.sock
pm = dynamiclistenはWebサーバーがリクエストを渡す場所で、8.3の標準値はUNIXソケットの[/run/php-fpm/www.sock]です。古いバージョンの標準値だった[127.0.0.1:9000]はTCPポートで受ける方式です。同じサーバーの中ではソケットのほうがポート接続の手順を踏まないぶん軽く、listen.ownerとlisten.groupでファイルの権限のようにアクセスを制限できます。
🔲 静的モードと動的モードの設定
pmはワーカーを起動する方式で、static・dynamic・ondemandのうち1つを指定します。静的モードはpm.max_childrenに書いた数を常に起動したままにし、下の設定はワーカー100個を維持します。
pm = static
pm.max_children = 100動的モードは標準値で、リクエスト量に応じてワーカー数が増減します。下の設定は、開始時に12個を起動し、待機中のワーカーを6個以上18個以下に保ち、最大120個まで増やします。
pm = dynamic
pm.max_children = 120
pm.start_servers = 12
pm.min_spare_servers = 6
pm.max_spare_servers = 18ondemandモードはリクエストが来たときだけワーカーを起動し、pm.process_idle_timeoutが過ぎると終了するので、アクセスが少ないサイトには合い、アクセスが多いサイトには合いません。
3つのモードは、ワーカーを起動するタイミングと増減の方式が違います。
| モード | ワーカーを起動する方式 | 向いているサイト |
|---|---|---|
| static(静的) | pm.max_childrenに書いた数を常に起動したままにする | アクセスが多いサイト |
| dynamic(動的) | 標準値 · リクエスト量に応じてpm.start_servers・pm.min_spare_servers・pm.max_spare_serversの範囲内で増減 | アクセス量が増減するサイト |
| ondemand | リクエストが来たときだけ起動し、pm.process_idle_timeoutが過ぎると終了 | アクセスが少ないサイト |
max_childrenは、サーバーのメモリをワーカー1つが使うメモリで割って決めます。[max_children]に達した警告がたまっても、すぐには上げずに、 ログでワーカーを埋めたリクエストから絞り込みます.
メモリとアップロードの上限はPHP全体の設定であるphp.iniで決め、運用するサイトに合わせてワーカー数と一緒に調整します。
memory_limit = 1024M
post_max_size = 128M
upload_max_filesize = 128M3つの値は、PHPスクリプト1つが使えるメモリの上限と、一度にアップロードできるファイルのサイズで、変更したあとはPHP-FPMを再起動しないと反映されません。
🔲 サイトアカウントごとのプール設定
サイトが複数ある場合は、www.conf1つを共有せず、アカウントごとにプールファイルを作って実行アカウントとソケットを分けます。1つのサイトのPHPが別のアカウントのファイルを読めなくなり、ワーカーの数もサイトごとに決められます。
vi /etc/php-fpm.d/siteuser.confファイルには、プール名、実行アカウント、ソケットのパス、ワーカー数を書きます。
[siteuser]
user = siteuser
group = nobody
listen = /run/php-fpm/siteuser.sock
listen.owner = siteuser
listen.group = nobody
listen.mode = 0660
pm = dynamic
pm.max_children = 50
pm.start_servers = 5
pm.min_spare_servers = 5
pm.max_spare_servers = 35
chdir = /home/siteuser/wwwlisten.ownerとlisten.groupはソケットファイルの所有者とグループで、PHP-FPMが起動するときにこの値でソケットを作ります。Webサーバーがnobodyアカウントで動いているならlisten.groupをnobodyに、apacheアカウントならapacheにして、Webサーバーがソケットを開けるようにします。
listen.owner = siteuser
listen.group = nobody
listen.mode = 0660この3行はプールファイルごとに入れ、値を変えたあとは再起動しないと、ソケットが新しい権限で作り直されません。
🔲 slowlogの設定
slowlogは、request_slowlog_timeoutより長くかかったリクエストの実行位置を記録するファイルで、値が0なら記録しません。遅いリクエストの原因を探すときに、3sのように秒単位で指定して有効にします。
slowlog = /var/log/php-fpm/www-slow.log
request_slowlog_timeout = 0記録されたファイルには、遅いリクエストのスクリプトのパスとそのとき実行中だった関数が残るので、どのプラグインやコードが時間を取ったのかを確認できます。
4️⃣ Apacheとの連携:VirtualHostの設定とソケットの権限
ApacheはPHPファイルへのリクエストを、mod_proxy_fcgiモジュールでプールのソケットに渡します。VirtualHostの中のFilesMatchにSetHandlerを1行入れ、サイトごとにそのアカウントのソケットを書きます。
# サイトアカウントごとにVirtualHostを1つ · SetHandlerにそのアカウントのソケットを指定(SetHandlerの代わりにProxyPassMatchでも接続できます)
<VirtualHost *:80>
ServerName example.com
ServerAlias www.example.com
DocumentRoot /home/siteuser/www
<Directory /home/siteuser/www>
Options -Indexes +FollowSymLinks
AllowOverride All
Require all granted
</Directory>
<FilesMatch \.php$>
SetHandler "proxy:unix:/run/php-fpm/siteuser.sock|fcgi://localhost"
</FilesMatch>
</VirtualHost>DocumentRootとDirectoryはそのアカウントのWebルートで、Optionsの-Indexesは、フォルダ一覧がブラウザに公開されるのを防ぎます。
🔲 ソケットの権限設定
プールを起動すると、listen.owner・listen.group・listen.modeの値でソケットが作られるので、権限が合っているかをlsで確認します。
ls -l /run/php-fpm/合計 4
srw-rw---- 1 siteuser_a nobody 0 10月 22 23:34 siteuser_a.sock
-rw-r--r-- 1 root root 7 10月 26 03:00 php-fpm.pid
srw-rw---- 1 siteuser_b nobody 0 10月 22 23:34 siteuser_b.sock
srw-rw----+ 1 root root 0 10月 22 23:34 www.sock権限がずれてWebサーバーがソケットを開けないと、訪問者は503エラーを受け取ります。再起動せずにすぐ合わせるときは、chownとchmodで所有者と権限を指定します。
ユーザーとグループをコロンで区切る、現在の書式です。
chown siteuser:nobody /run/php-fpm/siteuser.sock所有者を変えたあと、権限を660に合わせます。
chmod 660 /run/php-fpm/siteuser.sockユーザーとグループをドットで区切る古い書式で、AlmaLinux 9のchownでもそのまま実行できます。
chown siteuser.nobody /run/php-fpm/siteuser.sock所有者を変えたあと、権限を660に合わせます。
chmod 660 /run/php-fpm/siteuser.sock2つの書式の結果は同じで、どちらを使ってもソケットの所有者はsiteuser、グループはnobodyに変わります。
🔲 Nginxとの連携:fastcgi_passの設定
Nginxは、serverブロックの中のPHPファイル用locationで、fastcgi_passを使って同じプールのソケットにリクエストを渡します。
location ~ \.php$ {
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_pass unix:/run/php-fpm/siteuser.sock;
}Nginxがnginxアカウントで動いているなら、プールファイルのlisten.groupをnginxにしないとソケットを開けません。
5️⃣ 設定の検査と再起動:php-fpm -tとsystemctl
設定を変えたあとは、すぐに再起動せず、まずphp-fpm -tで構文を検査します。プールファイルに誤字があると、再起動のときにPHP-FPM全体が停止して、すべてのサイトが503を受け取るからです。
php-fpm -t[26-Oct-2026 17:33:45] NOTICE: configuration file /etc/php-fpm.conf test is successful検査を通過すると、設定ファイルのパスと一緒に[test is successful]というメッセージが表示され、その次にPHP-FPMへ反映します。ソケットのパスやlisten.ownerのように、ソケットを作り直す必要がある変更はrestartで反映します。運用中のサーバーでワーカー数のような値だけを変えたなら、reloadで反映します。
systemctl restart php-fpmVirtualHostを直したなら、Apacheも再起動します。
systemctl restart httpdサーバーを再起動したときに自動で実行されるよう、enableで登録します。
systemctl enable php-fpm登録されているかは、is-enabledで確認します。
systemctl is-enabled php-fpmenabledstatusで、プールごとにワーカーが起動しているかを確認します。
systemctl status php-fpm● php-fpm.service - The PHP FastCGI Process Manager
Loaded: loaded (/usr/lib/systemd/system/php-fpm.service; enabled; preset: disabled)
Active: active (running) since x
Process: 3934033 ExecReload=/bin/kill -USR2 $MAINPID (code=exited, status=0/SUCCESS)
Main PID: 1333314 (php-fpm)
Status: "Processes active: 4, idle: 21, Requests: x, slow: 0, Traffic: x"
Tasks: x
Memory: x
CPU: x
CGroup: /system.slice/php-fpm.service
├─ 41920 "php-fpm: pool siteuser_a"
├─ 94143 "php-fpm: pool siteuser_b"
├─1333314 "php-fpm: master process (/etc/php-fpm.conf)"
├─3934078 "php-fpm: pool www"
└─4009016 "php-fpm: pool siteuser_a"
10月 26 03:00:01 server.example.com systemd[1]: Reloading The PHP FastCGI Process Manager...
10月 26 03:00:01 server.example.com systemd[1]: Reloaded The PHP FastCGI Process Manager.Status行のactiveとidleは、いま処理中のワーカーと待機中のワーカーで、CGroupにはプール名ごとにワーカーが並びます。出力のホスト名とプール名は例の値に置き換えました。
🔢 FAQ & おすすめコンテンツ
ℹ️ 提携について
当サイトのコンテンツにはアフィリエイトリンクが含まれています。訪問者がこのリンクを通じて商品やサービスを購入すると、当サイトは販売元から手数料を受け取ります。この過程において、購入者が支払う金額(イベント割引適用で金額が下がります↓)は上昇しません。掲載されている価格・割引・在庫情報は作成時点のものであり、実際とは異なる場合がありますので、ご購入前に販売元にて最終確認をお願いいたします。商品の選定および評価は独自の基準に基づいて行われており、手数料の支払いの有無は紹介順や評価内容に影響を与えません。