Laravelをpublic/index.php に
ここでの
結論:Laravel×Nginx×PHP-FPMで見直す5つの設定
- Nginx:ドキュメントルートを
publicにし、PHPとして 実行するのは index.phpだけにする - PHP-FPM:
pmとpm.max_childrenを、サーバーの メモリと 同時に 受けたい リクエストの 数に 合わせる - OPcache:有効に
して、 PHPマニュアルの おすすめの 値から 始める - Laravelの
キャッシュ :デプロイのたびに php artisan optimizeを実行する - 本番の
設定 :APP_DEBUG=falseにし、storageとbootstrap/cacheをWebサーバーの ユーザーが 書き込めるように する
NginxでLaravelを動かす設定(公式の設定例)
Laravel 13.xのserver_name、root、fastcgi_pass は
server {
listen 80;
listen [::]:80;
server_name example.com;
root /srv/example.com/public;
add_header X-Frame-Options "SAMEORIGIN";
add_header X-Content-Type-Options "nosniff";
index index.php;
charset utf-8;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location = /favicon.ico { access_log off; log_not_found off; }
location = /robots.txt { access_log off; log_not_found off; }
error_page 404 /index.php;
location ~ ^/index\.php(/|$) {
fastcgi_pass unix:/var/run/php/php8.3-fpm.sock;
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
include fastcgi_params;
fastcgi_buffer_size 32k;
fastcgi_buffers 8 32k;
fastcgi_busy_buffers_size 64k;
fastcgi_hide_header X-Powered-By;
}
location ~ /\.(?!well-known).* {
deny all;
}
}
設定の
rootはプロジェクトの publicディレクトリを指します。 Laravelの 公式ドキュメントは、 public/index.phpをプロジェクトの いちばん上の ディレクトリへ 移してはいけないと しています。 移すと、 中の 設定ファイルなどが インターネットから 見えてしまう おそれが ある ためです (出典:Deployment (Laravel 13.x) )。try_filesで、ファイルが 見つからない リクエストを /index.phpに渡し、 Laravelの ルーティングで 処理します。 - PHP-FPMに
渡すのは index.phpへのリクエストだけです。 .envのようにドットで 始まる ファイルは deny allで見せません。 fastcgi_passのソケットの パスは、 PHP-FPM側の listenの値と 同じに します。 fastcgi_hide_header X-Powered-Byで、PHPの バージョンが 入る ヘッダーを 返さないように しています。
設定を
sudo nginx -t
sudo nginx -s reload
Laravel向けのPHP-FPMのプール設定
PHP-FPMは、/usr/local/etc/php-fpm.d/ に.conf ファイルを
次はpm.max_children などの
[www]
user = www-data
group = www-data
listen = /var/run/php/php8.3-fpm.sock
listen.owner = www-data
listen.group = www-data
listen.mode = 0660
pm = dynamic
pm.max_children = 20
pm.start_servers = 4
pm.min_spare_servers = 2
pm.max_spare_servers = 6
pm.max_requests = 500
request_terminate_timeout = 60s
request_slowlog_timeout = 5s
slowlog = /var/log/php-fpm/www-slow.log
pmの3つのモード
pm は
static:pm.max_childrenの数で 固定します。 dynamic:pm.max_children、pm.start_servers、pm.min_spare_servers、pm.max_spare_serversをもとに、 増やしたり 減らしたりします。 ondemand:起動した ときには 作らず、 リクエストが 来た ときに 作ります。 使われないまま pm.process_idle_timeoutの時間 (初期値は 10秒)が たった プロセスは 止めます。
pm.max_childrenの決め方
pm.max_children は、
pm.start_servers:起動した ときに 作る 子プロセスの 数。 初期値は min_spare_serversとmax_spare_serversの平均で、 dynamicのときだけ 使います。 pm.min_spare_servers・pm.max_spare_servers:待機している子プロセスの 数の 下限と 上限。 dynamicのときだけ 使います。 pm.max_requests:子プロセスが決まった 数の リクエストを 処理したら 作り直します。 外部の ライブラリーの メモリリーク対策に なり、 初期値の 0は 作り直しません。
(出典:FPMの
ソケットと権限
Nginxとlisten.owner・listen.group・listen.mode で、
PHPのlisten.allowed_clients で
OPcacheを有効にしてPHPを速くする
OPcacheは、
opcache.memory_consumption=128
opcache.interned_strings_buffer=8
opcache.max_accelerated_files=4000
opcache.revalidate_freq=60
opcache.enable_cli=1
opcache.validate_timestamps=0 にopcache_reset() か opcache_invalidate() を
Laravelのキャッシュで速くする(php artisan optimize)
本番の
php artisan optimize
ひとつずつphp artisan config:cache、php artisan event:cache、php artisan route:cache、php artisan view:cache をoptimize でphp artisan optimize:clear です。
config:cache を.env がenv() は null をenv() は config ディレクトリの
キューのphp artisan reload でphp artisan reload は
本番の設定とディレクトリの権限
- APP_DEBUG:本番では
必ず falseにします。 trueのままだと、 エラーの 画面に 設定の 中身などが 出てしまう おそれが あります (出典:Deployment (Laravel 13.x) )。 - 書き込める
場所 :bootstrap/cacheとstorageは、Webサーバーの プロセスを 動かすユーザーが 書き込めるようにします (出典:Deployment (Laravel 13.x) )。 - expose_php:
php.iniで設定する 項目で、 有効だと X-Powered-ByヘッダーでPHPの バージョンを 知らせます。 本番では expose_php = Offにします (出典:php.iniの コア設定 )。(PHPマニュアル)
権限をwww-data は、
sudo chown -R www-data:www-data storage bootstrap/cache
Docker(docker compose)でNginxとPHP-FPMを分けるとき
PHPのphp:8.4-fpm は、docker-php-ext-install でphp.ini-production を
FROM php:8.4-fpm
RUN docker-php-ext-install pdo_mysql opcache
RUN mv "$PHP_INI_DIR/php.ini-production" "$PHP_INI_DIR/php.ini"
WORKDIR /var/www/html
COPY . /var/www/html
Nginxとcompose.yaml のports にfastcgi_pass を app:9000 に、root を /var/www/html/public に
services:
app:
build: .
volumes:
- ./:/var/www/html
web:
image: nginx:stable
ports:
- "80:80"
volumes:
- ./:/var/www/html
- ./nginx/default.conf:/etc/nginx/conf.d/default.conf:ro
depends_on:
- app
ファイルのversion: は、
Nginx+PHP-FPMでよくあるトラブルと直し方
- Nginxから
PHP-FPMに :Nginxのつながらない fastcgi_passとPHP-FPMの listenが同じか。 ソケットの listen.owner・listen.group・listen.modeでNginxの ユーザーが 使えるか。 - 遅いリクエストが
どこで :止まっているか 分からない request_slowlog_timeoutとslowlogを設定すると、 時間が かかった リクエストの バックトレースが ログに 出る。 - 長い
処理が :途中で 止まる request_terminate_timeoutをこえると 子プロセスが 止められる。 CSVの 取り込みのような 重い 処理は、 Laravelの キューで 裏で 動かす。 - 時間が
たつと :メモリが 増えていく pm.max_requestsで子プロセスを 定期的に 作り直す。 - デプロイしても
古い :コードが 動く opcache.validate_timestamps=0のときは、 PHP-FPMを 再起動するか、 OPcacheを リセットする。 - .envの
値が :読めない config:cacheのあとは、 設定ファイルの 外の env()がnullになる。
(出典:FPMの
PHP-FPMのほかの選択肢(Laravel Octane)
Laravel Octaneは、
PHPとLaravelのサポート期間
| バージョン | セキュリティ修正の |
|---|---|
| PHP 8.2 | 2026年12月31日 |
| PHP 8.3 | 2027年12月31日 |
| PHP 8.4 | 2028年12月31日 |
| PHP 8.5 | 2029年12月31日 |
| Laravel 12 | 2027年2月24日 |
| Laravel 13 | 2028年3月17日 |
(2026年10月25日時点、
見直す順番(チェックリスト)
- Nginxの
rootがpublicになっていて、 PHPとして 実行するのが index.phpだけか確かめる - PHP-FPMの
pmとpm.max_childrenを、メモリに 収まる 数に する - OPcacheを
有効にし、 validate_timestampsを0に するなら デプロイで 再起動する - デプロイで
php artisan optimizeを実行する APP_DEBUG=falseとexpose_php = Offを確かめる
参考リンク
- Deployment
(Laravel 13.x) - FPMの
設定 (PHPマニュアル) - OPcache
(PHPマニュアル) - OPcacheの
インストール (PHPマニュアル) - OPcacheの
設定 (PHPマニュアル) - php.iniの
コア設定 (PHPマニュアル) - PHPの
サポート中の バージョン - Release Notes
(Laravel 13.x) - Queues
(Laravel 13.x) - Octane
(Laravel 13.x) - php
(Docker Hub 公式イメージ) - Version and name top-level elements
(Docker Docs) - docker-library/php 8.4 fpmの
Dockerfile - Command-line parameters
(nginx)

コメント