0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

nginxでphp-fpm を動かす設定

Posted at

概要

タイトル通り。Webサーバー上で PHP-FPM で動的サイトを構築したかったので。

環境

  • Ubuntu 24.04
  • nginx/1.28.0
  • php8.1-fpm (ondrej/php)
.bash
# nginx/1.28.0
nginx -v
nginx version: nginx/1.28.0

# php8.1-fpm がインストールされている
sudo dpkg -l php*-fpm | grep '^ii'
ii  php8.1-fpm     8.1.33-1+ubuntu24.04.1+deb.sury.org+1 amd64        server-side, HTML-embedded scripting language (FPM-CGI binary)

前提

Nginx のインストールは以下の筆者別記事にて実施済み:

( 公式の手順に沿って、バイナリをインストール )

方法

前提

  • PHPのマニュアル に Nginx 1.4.x の方法が書いてある。1.28.0 に読み替える必要がある。

  • また、上記マニュアルではすべてのバイナリと設定は /usr/local/nginx にあると想定されている。が、以下の点を読み替える。

    • 実際確認するとバイナリは /usr/sbin/nginx にあった。

    • 設定 (nginx.conf) は /etc/nginx/nginx.conf

      .bash
      # nginx ( バイナリインストール ) の場所を検索
      which nginx
      /usr/sbin/nginx
      
      # 設定ファイルの場所を検索
      sudo find / -path *nginx.conf*
      [sudo] password for xxx: 
      find: ‘/proc/117753/task/117753/net’: Invalid argument
      find: ‘/proc/117753/net’: Invalid argument
      /etc/nginx/nginx.conf    # <-- Here
      find: ‘/run/user/1000/gvfs’: Permission denied
      find: ‘/run/user/1000/doc’: Permission denied
      /var/lib/dpkg/info/nginx.conffiles
      

What added since Nginx 1.5.x so far

今回は CHANGELOG を見て、"HTTP", " port " などで検索し、関係ありそうな変更点は、その点をマニュアルで読み替える。変更の詳細は、GitHub を確認する。

"HTTP" でヒットした変更点

  • 1.9.4 の sub_filter ディレクティブ のバグが 1.9.5 で修正。→PHPのマニュアル で言及なし
  • postpone_output ディレクティブ の変更 ( 1.7.8 ) → 同じく、言及なし

" port " でヒットした変更点

  • mail proxy ( Eメールのプロキシ ), ngx_http_realip_module, proxy_bind, fastcgi_bind, memcached_bind, scgi_bind , and uwsgi_bind ディレクティブの機能追加 ( 1.27.3 など) → 同じく、言及なし

  • listen ディレクティブ の機能追加 :

    Changes with nginx 1.5.10
    Feature: port ranges in the "listen" directive.

    ポート範囲を指定する場合 は、注意が必要 ( ただし PHPのマニュアル で言及なし)

    → 下記、注意が必要。

    Changes with nginx 1.23.4

    Bugfix: port ranges in the "listen" directive did not work; the bug
    had appeared in 1.23.3.
    Thanks to Valentin Bartenev.

設定手順

公式の手順に沿って進めていきます。

事前準備

設定ファイルを取得し、正しい場所に移動します。

php.ini

.bash
# php.ini 設定ファイルのパスを検索
sudo find / -path *php.ini-*
[sudo] password for xxx:
/usr/lib/php/8.1/php.ini-production.cli
/usr/lib/php/8.1/php.ini-production
/usr/lib/php/8.1/php.ini-development    # <-- Here
.....

# php.ini 設定ファイルをコピー
sudo cp /usr/lib/php/8.1/php.ini-development /usr/local/php/php.ini

コピーした php.ini の以下の設定を追加。

ファイルが存在しなかったときは、Nginx が PHP-FPM バックエンドに、 リクエストを渡さないようにし、任意のスクリプトの挿入を防げるようにする

/usr/local/php/php.ini
; cgi.fix_pathinfo provides *real* PATH_INFO/PATH_TRANSLATED support for CGI.
cgi.fix_pathinfo=0

【任意】「コピー先のディレクトリがない」と、怒られる場合。

.bash
sudo cp /usr/lib/php/8.1/php.ini-development /usr/local/php/php.ini
cp: cannot create regular file '/usr/local/php/php.ini': No such file or directory

# 【任意】コピー先のディレクトリを作成
sudo mkdir -p /usr/local/php

php-fpm の設定ファイル

ppa の php8.1-fpm を使用しているためか、設定ファイルのパスが違いました:

.bash
# php-fpm 設定ファイルのパスを検索
sudo find / -path *fpm*conf*
/usr/lib/tmpfiles.d/php8.1-fpm.conf
find: ‘/proc/117753/task/117753/net’: Invalid argument
find: ‘/proc/117753/net’: Invalid argument
/etc/apache2/conf-available/php8.1-fpm.conf
/etc/php/8.1/fpm/pool.d/www.conf    # <-- Here
/etc/php/8.1/fpm/conf.d
/etc/php/8.1/fpm/conf.d/20-readline.ini
.....
...
/etc/php/8.1/fpm/conf.d/20-sysvmsg.ini
/etc/php/8.1/fpm/conf.d/20-ftp.ini
/etc/php/8.1/fpm/php-fpm.conf
find: ‘/run/user/1000/gvfs’: Permission denied
find: ‘/run/user/1000/doc’: Permission denied
/var/lib/dpkg/info/php8.1-fpm.conffiles

今回のように、ondrej/php から php8.1-fpm をインストールした場合、 /etc/php/8.1/fpm/pool.d/www.conf だと思われます。

PHPのマニュアルは古いせいか、www.conf.default をコピー元として www.conf というファイルを作っています。が、手元の私の環境では、www.conf がすでにあるので、逆にその www.conf を元に www.conf.default を作成することにします。
www.conf.default の存在理由は不明ですが。

.bash
# www.conf.default ファイルを作成 ( www.conf をコピー ) 
sudo cp /etc/php/8.1/fpm/pool.d/www.conf /etc/php/8.1/fpm/pool.d/www.conf.default

php-fpm の設定

まず www.conf の設定。

サービスを開始する前に、php-fpm が www-data ユーザーと www-data グループで 必ず実行されるように (中略)

.bash
sudo vim /etc/php/8.1/fpm/pool.d/www.conf

以下の部分を探し、修正します:

www.conf
[www]

; Unix user/group of the child processes. This can be used only if the master
; process running user is root. It is set after the child process is created.
; The user and group can be specified either by their name or by their numeric
; IDs.
; Note: If the user is root, the executable needs to be started with
;       --allow-to-run-as-root option to work.
; Default Values: The user is set to master process running user by default.
;                 If the group is not set, the user's group is used.
user = nginx
group = nginx

; Set permissions for unix socket, if one is used. In Linux, read/write
; permissions must be set in order to allow connections from a web server. Many
; BSD-derived systems allow connections regardless of permissions. The owner
; and group can be specified either by name or by their numeric IDs.
; Default Values: Owner is set to the master process running user. If the group
;                 is not set, the owner's group is used. Mode is set to 0660.
listen = /run/php/php8.1-fpm.sock
listen.owner = nginx
listen.group = nginx
+    listen.mode = 0660

;listen.allowed_clients = 127.0.0.1

+    slowlog = /var/log/php-fpm.log.slow
+    php_flag[display_errors] = off
+    php_admin_value[error_log] = /var/log/php-fpm.www-error.log
+    php_admin_flag[log_errors] = on

; The timeout for serving a single request after which a PHP backtrace will be
; dumped to the 'slowlog' file. A value of '0s' means 'off'.
; Available units: s(econds)(default), m(inutes), h(ours), or d(ays)
; Default Value: 0
;request_slowlog_timeout = 0
+    request_slowlog_timeout = 5s
.bash
# www-dataユーザー、 www-data グループが所有者になっている
ls -ld /run/php/php8.1-fpm.sock
srw-rw---- 1 nginx nginx 0 Oct 13 15:14 /run/php/php8.1-fpm.sock
ディレクティブ 説明 設定値 備考
user, group Unix ユーザー/グループ (子プロセス) nginx
listen FastCGI へのリクエストを受け付けるアドレス listen = <unixsocket> で Unix ソケットのパスを指定。
listen.owner, listen.group 読み取り、および書き込み権限 を持つ Unix ソケットファイルの所有者とグループ nginx
listen.mode Unix ソケットの読み取り・書き込み権限を Webサーバーへの接続に対して許可する 0660
listen.allowed_clients 接続が許可されている FastCGI クライアントの IPv4 or IPv6 アドレス のリスト default: any TCP ソケットの場合のみ有効
slowlog スローリクエストのログファイルパス /var/log/php-fpm.log.slow
request_slowlog_timeout リクエストを処理する際のタイムアウト。この時間を過ぎると PHP のバックトレースが 'slowlog' ファイルに出力される 5s Default Value: 0 ( = 'off' )
php_admin_value[error_log] PHP エラーログファイルパス /var/log/php-fpm.www-error.log
php_admin_flag[log_errors] PHP エラーログを有効にする on

www.conf のディレクティブは以下を参考.

ログファイルの権限:

.bash
# スローリクエストのログファイル
ls -ld /var/log/php-fpm.log.slow
-rwxrwxr-x 1 nginx nginx 0 Oct 11 11:35 /var/log/php-fpm.log.slow

# PHP エラーログファイル
ls -ld /var/log/php-fpm.www-error.log
-rwxrwxr-x 1 nginx nginx 0 Oct 11 11:36 /var/log/php-fpm.www-error.log

次に php-fpm.conf の設定。以下は初期値のまま:

/etc/php/8.1/fpm/php-fpm.conf
include=/etc/php/8.1/fpm/pool.d/*.conf
[global]
; Pid file
; Note: the default prefix is /var
; Default Value: none
; Warning: if you change the value here, you need to modify systemd
; service PIDFile= setting to match the value here.
pid = /run/php/php8.1-fpm.pid
  • pid:PID ファイルのパス

/etc/php-fpm.d/*.conf の概要

このディレクトリには、PHP-FPM の設定を分割して管理するための設定ファイルが「プール」単位で格納されています。デフォルトでは、www.confというプール設定ファイルが生成されています。

参考:

PHP-FPMの「プール」機能

  • プール単位でプロセス管理が可能。
  • アプリケーションごとにプールを分けて資源を最適化。
  • 主な構成要素:
    • マスター・プロセス:設定読み込みと管理
    • ワーカープロセス:PHPスクリプトの実行
    • リスナー(ソケット):Webサーバーとの通信

php-fpm サービスを起動:

ここまで来れば、php-fpm サービスを開始できます:

/usr/local/bin/php-fpm

実際は、PHPマニュアルとは 違いますので注意。
ondrej/php から php-fpm をインストールしていれば、単にそれが動いていれば OK

.bash
# 起動状態を確認。
sudo systemctl status php8.1-fpm
● php8.1-fpm.service - The PHP 8.1 FastCGI Process Manager
     Loaded: loaded (/usr/lib/systemd/system/php8.1-fpm.service; enabled; preset: enabled)
     Active: active (running) since Thu 2025-10-09 19:39:52 JST; 24h ago

# 起動していなければ.
sudo systemctl start php8.1-fpm

php-fpm のバイナリのコピー・実行は不要

.bash
# php-fpm のバイナリのパスを検索。
which php-fpm8.1
/usr/sbin/php-fpm8.1

# 上記のファイルをコピー
sudo cp /usr/sbin/php-fpm8.1 /usr/local/bin/php-fpm

このように、もし間違えて、PHP マニュアル通りに php-fpm サービスを呼び出すと、エラーになります:

.bash
sudo /usr/local/bin/php-fpm
[10-Oct-2025 20:13:51] ERROR: Another FPM instance seems to already listen on /run/php/php8.1-fpm.sock
[10-Oct-2025 20:13:51] ERROR: FPM initialization failed

nginx の設定

Nginx が PHP アプリケーションの実行をサポートするように設定しなければなりません。

下のnginx.conf で追加した要素についてはあとで説明します。とりあえず全行 :

/etc/nginx/nginx.conf

user  nginx;
worker_processes  auto;

error_log  /var/log/nginx/error.log debug;
pid        /run/nginx.pid;


events {
    worker_connections  1024;
}


http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    keepalive_timeout  65;

    #gzip  on;

    include /etc/nginx/conf.d/*.conf;


    server {
        listen    80;
        root      /usr/share/nginx/html;

        server_name localhost;

        location / {
            index  index.php index.html index.htm;
            try_files $uri $uri/ /index.php;
        }

        location ~* \.php$ {
            try_files $uri =404;
            fastcgi_split_path_info ^(.+?\.php)(/.+)?$;
            # NOTE: You should have "cgi.fix_pathinfo = 0;" in php.ini

            fastcgi_index   index.php;
            fastcgi_pass    unix:/run/php/php8.1-fpm.sock;
            # fastcgi_pass localhost:9000;
            include         fastcgi_params;
            fastcgi_param   SCRIPT_FILENAME    /usr/share/nginx/html$fastcgi_script_name;
            fastcgi_param   SCRIPT_NAME        $fastcgi_script_name;
        }
    }
}
.bash
# nginx を再起動
 sudo /usr/sbin/nginx -s stop
 sudo systemctl start nginx
.bash
# テスト用 PHP ファイル を作成。
echo "<?php phpinfo(); ?>" | sudo tee /usr/share/nginx/html/index.php > /dev/null
.bash
# index.html を削除
sudo rm /usr/share/nginx/html/index.html

ドキュメントルートの所有者(nginx) と権限 ( ディレクトリは 755, ファイルは 644 )

.bash
# 所有者とグループを nginx に。
sudo chown -R nginx:nginx /usr/share/nginx/html

# ドキュメントルートのディレクトリは 755に、
sudo find /usr/share/nginx/html -type d -exec chmod 755 {} +
# ファイルは 644 に設定する
sudo find /usr/share/nginx/html -type f -exec chmod 644 {} +

# 権限・所有者・グループ確認 (ディレクトリ)
ls -ld /usr/share/nginx/html
drwxr-xr-x 2 nginx nginx 4096 Oct 11 21:12 /usr/share/nginx/html

# 同 (ファイル)
ls -al /usr/share/nginx/html
total 16
drwxr-xr-x 2 nginx nginx 4096 Oct 11 21:12 .
drwxr-xr-x 3 root  root  4096 Oct  9 17:04 ..
-rw-r--r-- 1 nginx nginx  497 Apr 23 20:48 50x.html
-rw-r--r-- 1 nginx nginx   20 Oct 11 08:53 index.php

default.conf の設定と server_name が被るので、デフォルトの設定ファイルを無効化しておく。

.bash
# デフォルトの設定ファイルを無効化
sudo mv /etc/nginx/conf.d/default.conf /etc/nginx/conf.d/default._conf

# 設定ファイルのテスト
sudo nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

# 設定ファイルの再読み込み
sudo nginx -s reload

# nginx と php-fpm を再起動
sudo systemctl restart nginx && sudo systemctl restart php8.1-fpm

トラブルシューティング (nginxの設定)

  1. ドキュメントルートの index.php の URI にWebブラウザでアクセスすると、index.php ファイルがダウンロードされる場合:

    nginx.conf
    location ~* \.php$ {
    +         try_files $uri =404;
    +         fastcgi_split_path_info ^(.+?\.php)(/.+)?$;
             # NOTE: You should have "cgi.fix_pathinfo = 0;" in php.ini
    

    設定内容はあまり理解できていないが、とりあえずリンクを貼っておく:

  1. nginx -t すると、nginx: [warn] conflicting server name "localhost" on 0.0.0.0:80, ignored になる場合:

    上にも書いたが、以下を実行。

    .bash
    # デフォルトの設定ファイルを無効化
    sudo mv /etc/nginx/conf.d/default.conf /etc/nginx/conf.d/default._conf
    

参考


nginx.conf の説明

実際に追加したのは、以下の要素 ( server ディレクティブのコンテキスト) :

コンテキスト 説明 設定値
listen 80
root サイトのルートディレクトリ /usr/share/nginx/html
location の index ブラウザ等からlocalhost などに "/" だけを付けた URI にアクセスした場合、root のディレクトリに指定したファイルが存在するかを調べる。そしてマッチしたファイルにリダイレクトする。 index.php index.html index.htm
location の try_files $uri あるいは $uri/ を探す。なければ /index.php を探す $uri $uri/ /index.php
2つ目のlocation の fastcgi_index, fastcgi_param SCRIPT_FILENAME /の URI にアクセスしたときに返すファイル index.php, /usr/share/nginx/html$fastcgi_script_name
fastcgi_param SCRIPT_NAME 同上 $fastcgi_script_name
fastcgi_pass php-fpm のUnix ソケットのパス unix:/run/php/php8.1-fpm.sock

ログの設定

  • ログレベルをdebug に変更:
ディレクティブ 説明 設定値
error_log エラーログのパスとログのレベル /var/log/nginx/error.log debug

参考: A simple PHP site configuration の例

Fast CGI パラメータの読み込み

  • include fastcgi_params/etc/nginx/fastcgi_params を読み込む。
  • その下の行で、fastcgi_param SCRIPT_FILENAME など、上記のfastcgi_paramsファイルを上書きしたい値を設定する。(逆にすると、nginx.conf が上書きされてしまい、効果がなくなるので注意)

設定にてこずってQiitaは後から書いたので、listen とかは追加したかもとからあったか、うろおぼえですが。あと、バックアップしてなかったので。
なお、セミコロン (";" ) が文末に必要なので注意。

注意

/usr/share/nginx/html/index.html は削除してください。location の index コンテキストに影響します。

.bash
sudo rm /usr/share/nginx/html/index.html

上記のように設定した index コンテキストだと、リクエストされた root のディレクトリのファイルに対して、index.html がなかった場合に、index.php にマッチング します。

つまり、PHP の動的サイトを作る場合は、index.html を削除し、index.php だけを作成 する、という事になります。

http://localhost/index.php にアクセスします:

image.png

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?