PHP-FPMとは | PHP-FPMのインストールと設定

テスト環境 RHEL系AlmaLinux 9.8Apache 2.4 + PHP-FPM 8.3rootアカウント2026-10-26 確認

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の設定を使います。

🧩 CGIとPHP-FPMのリクエスト処理
解説ダイアグラム
⚙️ PHPの実行
🌐 Webサーバー
🌐 ApacheNginx
📨 リクエスト1 · index.php📨 リクエスト2 · wp-login.php📨 リクエスト3 · index.php
静的ファイル(画像・CSS)はWebサーバーが直接応答
リクエストごとに実行FastCGI · ソケット→
🧱 CGIプロセス
リクエスト1新しいプロセス → 処理 → 終了
リクエスト2新しいプロセス → 処理 → 終了
リクエスト3新しいプロセス → 処理 → 終了
処理が終わるとプロセスも消える · 次のリクエストはまた最初から
🧰 PHP-FPMのプール [siteuser]
ワーカー1リクエスト1
ワーカー2リクエスト2
ワーカー3リクエスト3
ワーカー4待機
ワーカー5待機
あらかじめ起動したワーカーがリクエストを受け、終わったら次のリクエストを待つ
ApacheがCGIでPHPを実行すると、リクエストのたびにPHPプロセスを新しく起動して処理が終わると終了するため、リクエストが増えるほどプロセスを作るコストが積み重なります。
NginxにはCGIプログラムを直接実行するモジュールがないため、この組み合わせは使わず、PHPはFastCGIでPHP-FPMに渡します。
Apacheはmod_proxy_fcgiでPHPのリクエストをソケットに渡し、あらかじめ起動しておいたPHP-FPMのワーカーが受け取って処理し、次のリクエストを待ちます。
Nginxはfastcgi_passで同じソケットに渡すので、Webサーバーが違ってもPHP-FPMのプールは1つで同じです。

2️⃣ PHP-FPMのインストール:パッケージの確認とdnfでのインストール

RHEL系サーバーでdnfを使ってPHPをインストールしたなら、php-fpmパッケージも一緒にインストールされています。まずrpmでインストールされているかを確認します。PHPのインストール手順は Rocky Linux APMのインストールと同じです。

rpm -qa | grep php-fpm
php-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.conf
listen = /run/php-fpm/www.sock
pm = dynamic

listenは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 = 18

ondemandモードはリクエストが来たときだけワーカーを起動し、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 = 128M

3つの値は、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/www

listen.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.sock

2つの書式の結果は同じで、どちらを使ってもソケットの所有者は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-fpm

VirtualHostを直したなら、Apacheも再起動します。

systemctl restart httpd

サーバーを再起動したときに自動で実行されるよう、enableで登録します。

systemctl enable php-fpm

登録されているかは、is-enabledで確認します。

systemctl is-enabled php-fpm
enabled

statusで、プールごとにワーカーが起動しているかを確認します。

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 & おすすめコンテンツ

mod_phpはApacheプロセスの中でPHPを実行するため設定は簡単ですが、ApacheのワーカーごとにPHPが読み込まれてメモリを多く使い、実行アカウントをサイトごとに分けにくくなります。PHP-FPMはPHPを別のプロセスに分離するので、サイトごとにアカウントとワーカー数を決められます。サイトが複数あるサーバーやNginxを使うサーバーでは、PHP-FPMを使います。

systemctl reload php-fpmは、マスタープロセスにUSR2シグナルを送って設定を読み直し、ワーカーを入れ替えます。process_control_timeoutを指定すると、処理中のリクエストを終えたワーカーから入れ替えます(公式ドキュメントによる)。restartはすべてのワーカーを一度に停止して起動し直すため、その瞬間のリクエストが途切れることがあります。運用中のサーバーではまずreloadを使います。

RHEL系の標準のログは[/var/log/php-fpm/error.log]で、ワーカー不足の警告(seems busy・max_children)とプールの開始・停止の記録がここに残ります。プールごとにphp_admin_value[error_log]で指定したファイルには、そのサイトのPHPコードのエラーが別に記録されます。標準のプールは[/var/log/php-fpm/www-error.log]に記録されます。

ℹ️ 提携について
当サイトのコンテンツにはアフィリエイトリンクが含まれています。訪問者がこのリンクを通じて商品やサービスを購入すると、当サイトは販売元から手数料を受け取ります。この過程において、購入者が支払う金額(イベント割引適用で金額が下がります↓)は上昇しません。掲載されている価格・割引・在庫情報は作成時点のものであり、実際とは異なる場合がありますので、ご購入前に販売元にて最終確認をお願いいたします。商品の選定および評価は独自の基準に基づいて行われており、手数料の支払いの有無は紹介順や評価内容に影響を与えません。

コメントを残す

メールアドレスが公開されることはありません。 ※ が付いている欄は必須項目です

人間であることを証明してください: 10   +   3   =