2026年5月17日
2026年5月17日
Apache と PHP-FPM の連携設定(UNIX ソケット)|mod_proxy_fcgi の書き方、サイト別プール、動作確認
Apache で PHP を動かす方法には、Apache のプロセスに PHP を組み込む mod_php と、PHP を別プロセスの PHP-FPM で動かし、Apache から FastCGI で処理を渡す方法があります。PHP-FPM を使う場合、Apache と PHP-FPM の間の接続には、TCP(例: 127.0.0.1:9000)か UNIX ドメインソケット(例: /run/php/php8.3-fpm.sock)を使います。
同じサーバーの中で接続するなら、UNIX ソケットが一般的です。ネットワークのポートを開けずに済み、ソケットファイルの所有者と権限で、接続できるプロセスを絞れます。PHP-FPM を別のサーバーで動かす場合は TCP を使います。
この記事では、Ubuntu 24.04(Apache 2.4、PHP 8.3)で確認した設定をもとに、ソケットでの接続、サイトごとのプールとソケットの分け方、動作の確認、うまく動かないときの見分け方を説明します(2026年10月時点)。PHP のバージョンが違う場合は、パスやサービス名の 8.3 を読み替えてください。
PHP-FPM をインストールし、ソケットを確認する
sudo apt update
sudo apt install apache2 php8.3-fpm
Ubuntu / Debian の PHP-FPM は、最初からソケットで待ち受ける設定になっています。プールの設定 /etc/php/8.3/fpm/pool.d/www.conf の該当部分は次のとおりです。
user = www-data
group = www-data
listen = /run/php/php8.3-fpm.sock
listen.owner = www-data
listen.group = www-data
;listen.mode = 0660
listen がソケットのパス、listen.owner / listen.group / listen.mode がソケットファイルの所有者と権限です。Apache(www-data ユーザー)がこのソケットに読み書きできる必要があります。
PHP-FPM が動いていれば、ソケットファイルができています。
sudo systemctl status php8.3-fpm
ls -l /run/php/
srw-rw---- 1 www-data www-data ... php8.3-fpm.sock のように表示されれば待ち受けています。先頭の s はソケットであることを表します。
Apache から PHP-FPM のソケットへ渡す
Apache 側では、mod_proxy_fcgi と、PHP-FPM 用に用意された設定ファイルを有効にします。
sudo a2enmod proxy_fcgi setenvif
sudo a2enconf php8.3-fpm
a2enconf php8.3-fpm で有効になる /etc/apache2/conf-available/php8.3-fpm.conf には、PHP ファイルへのリクエストをソケットへ渡す次の設定が含まれています。
<FilesMatch ".+\.ph(?:ar|p|tml)$">
SetHandler "proxy:unix:/run/php/php8.3-fpm.sock|fcgi://localhost"
</FilesMatch>
proxy:unix: の後ろがソケットのパスで、|fcgi://localhost は FastCGI で渡すことを表す決まった書き方です。ソケットで接続するときは、ホスト名の部分に localhost と書きます。この設定ファイルは mod_php が有効なときは働かないようになっているので、mod_php を使っていた場合は無効にします。
# mod_php が有効だった場合だけ実行する
sudo a2dismod php8.3 mpm_prefork
sudo a2enmod mpm_event
mod_php はスレッドを使わない mpm_prefork が必要ですが、PHP-FPM を使うなら、同時接続に強い mpm_event に切り替えられます。
構文を確かめてから、Apache を再起動します。
sudo apache2ctl configtest
sudo systemctl restart apache2
PHP-FPM で動いているか確認する
ドキュメントルートに確認用のファイルを置きます。
<?php
echo PHP_SAPI;
/var/www/html/sapi.php として保存し、ブラウザか curl で開きます。
curl http://localhost/sapi.php
fpm-fcgi と表示されれば、PHP-FPM で処理されています。apache2handler と表示される場合は mod_php で動いています。確認が終わったら、このファイルは削除してください。
サイトごとにプールとソケットを分ける
1台のサーバーで複数のサイトを動かす場合、サイトごとに PHP-FPM のプールを分け、別の OS ユーザーで実行すると、あるサイトの PHP が別のサイトのファイルを書き換えることを防げます。プールごとにソケットを分け、VirtualHost ごとに接続先を指定します。
プールを作る
ここでは site1 というユーザーでサイトを動かす例です。ユーザーとファイルの所有者を用意しておきます。
sudo useradd -r -s /usr/sbin/nologin site1
sudo chown -R site1:site1 /var/www/site1
/etc/php/8.3/fpm/pool.d/site1.conf を作ります。
[site1]
user = site1
group = site1
listen = /run/php/php8.3-fpm-site1.sock
listen.owner = www-data
listen.group = www-data
listen.mode = 0660
pm = dynamic
pm.max_children = 10
pm.start_servers = 2
pm.min_spare_servers = 1
pm.max_spare_servers = 3
user/groupは PHP を実行するユーザーです。サイトのファイルの所有者に合わせます。listen.owner/listen.groupはソケットファイルの所有者です。ここは Apache が接続できるようにwww-dataにします。pm.max_childrenは同時に動く PHP プロセスの上限です。1プロセスが使うメモリ量とサーバーのメモリから決めます。
設定を確かめてから、PHP-FPM を読み込み直します。
sudo php-fpm8.3 -t
sudo systemctl reload php8.3-fpm
ls -l /run/php/
php8.3-fpm-site1.sock ができていれば、新しいプールが待ち受けています。
VirtualHost で接続先を指定する
サイトの VirtualHost に、そのプールのソケットを指定します。
<VirtualHost *:80>
ServerName site1.example.com
DocumentRoot /var/www/site1
<FilesMatch "\.php$">
SetHandler "proxy:unix:/run/php/php8.3-fpm-site1.sock|fcgi://localhost"
</FilesMatch>
<Directory /var/www/site1>
AllowOverride All
Require all granted
</Directory>
</VirtualHost>
VirtualHost の中の設定は、サーバー全体の設定(php8.3-fpm.conf)より後に適用されるので、このサイトの PHP は site1 のプールで処理されます。ほかのサイトは、これまでどおり www プールのソケットを使います。
sudo a2ensite site1.conf
sudo apache2ctl configtest
sudo systemctl reload apache2
確認用に、次の内容のファイルをサイトに置いて開くと、実行しているユーザー名が分かります(確認後は削除します)。
<?php
echo PHP_SAPI, ' ', get_current_user(), ' ', posix_getpwuid( posix_geteuid() )['name'];
posix_geteuid() で取れるのが実際に PHP を動かしているユーザーです(get_current_user() はファイルの所有者を返します)。fpm-fcgi site1 site1 のように表示されれば、site1 のプールで動いています。
うまく動かないときの見分け方
Apache のエラーログ(/var/log/apache2/error.log)に、原因に応じた記録が残ります。接続に失敗したときは、表の記録に続けて AH01079: failed to make connection to backend: httpd-UDS も記録されます。
| 症状 | エラーログの例 | 主な原因と対処 |
|---|---|---|
| 503 Service Unavailable | (13)Permission denied: AH02454: FCGI: attempt to connect to Unix domain socket ... failed |
ソケットの所有者・権限が合わず、Apache が接続できない。listen.owner / listen.group を www-data にし、listen.mode = 0660 にする |
| 503 Service Unavailable | (2)No such file or directory: AH02454: FCGI: attempt to connect to Unix domain socket ... failed |
PHP-FPM が止まっている、またはソケットのパスが SetHandler と listen で一致していない |
| PHP のコードがそのまま表示・ダウンロードされる | 記録なし | proxy_fcgi が無効、または SetHandler が書かれていない |
画面は出るが apache2handler と表示される |
記録なし | mod_php が有効なまま。a2dismod php8.3 で無効にする |
PHP-FPM 側の状態は、次のコマンドで確認します。
sudo systemctl status php8.3-fpm
sudo journalctl -u php8.3-fpm --since "10 min ago"
sudo tail -n 50 /var/log/php8.3-fpm.log
server reached pm.max_children setting という警告が出ている場合は、同時に処理できるプロセスが足りていません。メモリに余裕があれば pm.max_children を増やし、余裕がなければ遅い処理(重いプラグインなど)を見直します。
RHEL 系(AlmaLinux・Rocky Linux)での違い
RHEL 系の php-fpm パッケージでは、パスやユーザー名が次のように異なります。
| 項目 | Ubuntu / Debian | RHEL 系 |
|---|---|---|
| プールの設定 | /etc/php/8.3/fpm/pool.d/www.conf |
/etc/php-fpm.d/www.conf |
| 既定のソケット | /run/php/php8.3-fpm.sock |
/run/php-fpm/www.sock |
| Apache 側の設定 | /etc/apache2/conf-available/php8.3-fpm.conf |
/etc/httpd/conf.d/php.conf |
| Apache のユーザー | www-data |
apache |
| サービス名 | php8.3-fpm、apache2 |
php-fpm、httpd |
RHEL 系では、ソケットへの接続を許すユーザーを listen.acl_users で指定していることがあります。プールを増やすときは、既定の www.conf の listen.* の書き方に合わせてください。
まとめ
- 同じサーバー内なら、Apache と PHP-FPM は UNIX ソケットでつなぐのが一般的。ポートを開けずに済み、ソケットの権限で接続元を絞れる。
- Ubuntu / Debian では
a2enmod proxy_fcgi setenvifとa2enconf php8.3-fpmで、SetHandler "proxy:unix:/run/php/php8.3-fpm.sock|fcgi://localhost"が有効になる。 PHP_SAPIがfpm-fcgiになっていることで、PHP-FPM で動いていることを確認する。- サイトごとにプールとソケットを分け、
userはサイトのユーザー、listen.owner/listen.groupは Apache のユーザーにする。 - 503 のときは Apache のエラーログで、権限の問題(Permission denied)か、PHP-FPM の停止・パスの不一致かを見分ける。