PHP 向けの Web サーバーおよびランタイム設定のカスタマイズ
この記事の英語版に更新があります。ご覧の翻訳には含まれていない変更点があるかもしれません。
最終更新日 2024年05月04日(土)
Table of Contents
PHP には、Heroku Web dyno での実行に使用できる組み込みの Web サーバーがありますが、これは推奨されていません。代わりに、Procfile
で参照されるブートスクリプトを使用し、PHP と共に Web サーバーを起動してください。
この記事では、このブートスクリプトに引数を渡して、PHP ランタイムや Web サーバーソフトウェアの設定をカスタマイズするさまざまな方法について説明します。
dyno のブート中にアプリケーションが起動される仕組み
デプロイ中、Heroku によって、Composer パッケージの heroku/heroku-buildpack-php が追加の依存関係としてアプリケーションにインストールされます。このパッケージには、Apache または Nginx いずれかの Web サーバーと共に PHP を起動するためのブートスクリプトが含まれています。
使用できるブートスクリプトの名前は次のとおりです。
heroku-php-apache2
(PHP および Apache2 用)heroku-php-nginx
(PHP および Nginx 用)
heroku/heroku-buildpack-php
パッケージによってインストールされるこれらのブートスクリプトは、$PATH
に配置され、vendor/heroku/heroku-buildpack-php/conf/
の設定ファイルを使用して、選択した Web サーバーと共に PHP-FPM を起動します。
Heroku では、同じパッケージをローカルで実行することによって、開発/本番パリティを維持することを推奨しています。本番環境で実行しているパッケージを composer.json
ファイルの require-dev
セクションに追加することによって、開発依存関係として使用できます。以後、開発用マシンでシームレスに機能するローカル開発環境を起動できますが、Apache または Nginx がインストールされていることが条件になります。
heroku/heroku-buildpack-php
パッケージをローカルにインストールすれば、任意のブートスクリプトのヘルプ画面を表示できるようになります。ブートスクリプトに指定できるさまざまなオプションと引数を使用して、PHP や Web サーバーソフトウェアに関連した設定を制御できます。上記のリストにあるインストール済みバイナリはどれも、--help
フラグを指定して実行することで、詳細なヘルプを表示できます。たとえば、PHP と Apache を起動するためのオプションに関するヘルプを表示するには、次のコマンドを実行します。
$ heroku-php-apache2 --help
使用するランタイムの指定
サポートされている機能およびバージョンについての詳細は、PHP リファレンスの記事を参照してください。
Procfile
の設定方法と、アプリケーションの設定をカスタマイズするために使用できる引数については、以下のセクションを参照してください。
使用する Web サーバーの指定
Procfile
では、このドキュメントで先に挙げたブートスクリプトのどちらを使用するかを指定する必要があります。dyno が起動すると、Heroku によって、対応する Web サーバーが PHP と共に起動されます。
たとえば、PHP と共に Nginx を使用するには、次の内容を Procfile
に含める必要があります。
web: heroku-php-nginx
ドキュメントルートの設定
アプリケーションに必要な設定カスタマイズで最も一般的なものは、いわゆるドキュメントルートです。
ドキュメントルートは、アプリケーションが .php
ファイルの探索を開始するディレクトリです。ドキュメントルートを変更するには、ブートスクリプトへの引数として (アプリケーションのルートディレクトリからの相対パスで) ディレクトリのパスを指定します。ドキュメントルートを定義するために、設定ファイルの変更やルールの書き直しは必要ありません。
たとえば、Apache と PHP を使用していて、(index.php
とすべての画像、CSS、JavaScript が入っているという理由で) アプリケーションの public
サブディレクトリをドキュメントルートに設定する場合、Procfile
は次のようになります。
web: heroku-php-apache2 public/
(後述するように) スクリプトに追加のオプションを指定する場合、次の例のように、ドキュメントルート引数は必ずコマンドの最後 (すべてのオプションよりも後) に置く必要があります。
web: heroku-php-nginx -C rewrite.conf www/
ドキュメントルートを定義しない (アプリケーションのルートディレクトリをドキュメントルートにする) 場合は、引数を省略するだけです。
web: heroku-php-apache2
デフォルトの動作
Heroku によって FastCGI Process Manager (PHP-FPM) アプリケーションサーバーが起動されます。このアプリケーションサーバーは、Apache または Nginx いずれかの Web サーバーから PHP ファイルの実行リクエストを受け付けます。
Web サーバーは $PORT
環境変数のポートにバインドし、受信 HTTP リクエストに応答します。名前が .php
で終わる既存のファイルがリクエストの対象である場合、Web サーバーは FastCGI プロトコルを使用して、この PHP ファイルの実行リクエストをアプリケーションサーバーに渡します。
これらの Web サーバーの設定はカスタマイズできます。
デフォルトの設定は、選択した Web サーバー (Apache または Nginx) によって異なります。以下に、それぞれのデフォルト設定について説明します。
Apache のデフォルト設定
Apache では、すべてのホスト名に応答するバーチャルホストを使用します。ドキュメントルートは、アクセス制限なしで到達可能な <Directory>
として設定され、.htaccess
ファイルの使用を有効にするために AllowOverride All
が設定されます。.php
で終わる URL へのリクエストは、fcgi://heroku-fcgi
という名前のプロキシエンドポイントを使用して、mod_proxy_fcgi を介して PHP-FPM に書き換えられます。DirectoryIndex
ディレクティブは “index.php index.html index.html
” に設定されます。
Nginx のデフォルト設定
Nginx では、すべてのホスト名に応答する server
を使用します。ドキュメントルートにはアクセス制限はありません。.php
を含む URL へのリクエストは、URL 全体に対する try_files
呼び出しの後、 “heroku-fcgi” というアップストリームを使用して、PHP-FPM で fastcgi_pass
によってレンダリングされます。index
ディレクティブは “index.php index.html index.html
” に設定されます。
Web サーバーの設定
サイト固有の独自の設定を指定することによって Apache または Nginx を設定できます。
Apache
.htaccess
の使用
通常の .htaccess ファイルを使用して Apache HTTP サーバーの動作をカスタマイズできます。ドキュメントルートの AllowOverride
オプションは all
に設定されます。つまり、.htaccess
のコンテキストで許可されている任意の設定ディレクティブを使用できます。
カスタムの (また、潜在的にエラーが発生しやすい) 設定インクルードを使用する必要がないため、これは Apache 設定をカスタマイズするための推奨アプローチです。
アプリケーションレベルのカスタム Apache 設定の使用
Apache の起動時に Heroku が使用するデフォルトのサーバーレベル設定ファイルの内部には、ごく単純なデフォルトのアプリケーションレベル設定ファイルが含まれています。このファイルをカスタム設定に置き換えることができます。たとえば、Symfony2 アプリケーション向けの何らかの書き換えルールを使用するように Apache を設定するには、次の内容を含む apache_app.conf
をアプリケーションのルートディレクトリ内に作成します。
RewriteEngine On
RewriteCond %{REQUEST_URI}::$1 ^(/.+)/(.*)::\2$
RewriteRule ^(.*) - [E=BASE:%1]
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteRule ^app\.php(/(.*)|$) %{ENV:BASE}/$2 [R=301,L]
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule .? - [L]
RewriteRule .? %{ENV:BASE}/app.php [L]
この特定のケースでは、対応する書き換えルールを .htaccess
ファイルに入れることもできます。実際に、このスニペットはその全体が Symfony Standard Edition の .htaccess
ファイルからコピーされたものです。
次に、ブートスクリプトの -C
引数を使用して、このファイルを自動的にインクルードするよう Heroku に指示できます。
web: heroku-php-apache2 -C apache_app.conf
どのコンテキストでこの設定ファイルがインクルードされるかを把握するには、起動時に Heroku によってシステム全体の設定ファイルの直後に読み込まれる Apache 向けのサーバーレベル設定を確認することをお勧めします。
Nginx
アプリケーションレベルのカスタム Nginx 設定の使用
Nginx の起動時に Heroku が使用するデフォルトのサーバーレベル設定ファイルの内部には、ごく単純なデフォルトのアプリケーションレベル設定ファイルが含まれています。このファイルをカスタム設定に置き換えることができます。たとえば、Symfony アプリケーション向けのいくつかの書き換えルールを使用するように Nginx を設定するには、次の内容を含む nginx_app.conf
をアプリケーションのルートディレクトリ内に作成します。
location / {
# try to serve file directly, fallback to rewrite
try_files $uri @rewriteapp;
}
location @rewriteapp {
# rewrite all to index.php
rewrite ^(.*)$ /index.php/$1 last;
}
location ~ ^/index\.php(/|$) {
try_files @heroku-fcgi @heroku-fcgi;
# ensure that /index.php isn't accessible directly, but only through a rewrite
internal;
}
上記の設定内の internal;
ディレクティブは、書き換えからのものでない場合は /index.php
などの呼び出しが許可されないことを保証します。
try_files @heroku-fcgi @heroku-fcgi;
を使用すればいつでも、"@heroku-fcgi
" という名前の場所を使用して、.php
ファイル用のデフォルトルールに処理を委任できます。これは、PHP を呼び出す最も簡単で移植性の高い方法です。
代わりに fastcgi_pass
を使用するときは、"heroku-fcgi
" を宛先として使用します。これはアップストリームグループであり、FastCGI リクエストが常に正しいバックエンドプロセスに渡されるように設定されます。
新しいデフォルト設定を作成したら、ブートスクリプトの -C
引数を使用して、この設定で起動するようアプリケーションに指示できます。
たとえば、独自の nginx_app.conf
を記述した場合、この設定ファイルを使用するように Procfile
を変更できます。
web: heroku-php-nginx -C nginx_app.conf
どのコンテキストでこの設定ファイルがインクルードされるかを把握するには、起動時に Heroku によってシステム全体の設定ファイルの直後に読み込まれる Nginx 向けのサーバーレベル設定を確認することをお勧めします。
PHP ランタイム設定
INI 設定
Heroku では、php.ini
設定を変更するために PHP で提供されている複数の方法をサポートしています。
実行時に PHP コードで ini_set
を使用することに加えて、PHP-FPM 用の追加設定ファイルを使用するように Heroku を設定することもできます。この設定ファイルは、INI ディレクティブを含めることができ、起動時にデフォルト設定よりも後に読み込まれます。
ほとんどのケースで推奨されるアプローチは、PHP-FPM によって自動的に選択されるディレクトリごとの .user.ini
ファイルです。
ワーカープロセスは PHP-FPM を使用しないため、以下の方法は web
dyno にしか適用されませんが、通常は php
実行可能ファイルを直接起動するため、-d
コマンドラインオプションを使用して INI ディレクティブを渡すことができます。
.user.ini
ファイル (推奨)
PHP-FPM は、Web サーバー経由で提供されている .php
ファイルと同じディレクトリに .user.ini
ファイルがあれば、そのファイルから設定を読み取ります。見つからない場合は、アプリケーションに設定したドキュメントルートまでのいずれかの親ディレクトリにある .user.ini
ファイルからも設定を読み取ります。
Heroku では、.user.ini
ファイルを使用して Web トラフィック用に PHP 設定をカスタマイズすることを推奨しています。この機能の詳細と、この機能を使用して制御できる設定については、PHP マニュアルの .user.ini
ファイルに関するセクションを参照してください。
たとえば、HTML フォームからアップロードされる 1 つのファイルの最大サイズを 5 MB に、合計 POST
サイズを 20 MB に変更するには、次の内容を含む .user.ini
をドキュメントルートに配置します。
post_max_size = 20M
upload_max_filesize = 5M
PHP-FPM 設定インクルード
PHP.ini
設定ディレクティブの小さなセットは、.user.ini
を使用して変更できません。たとえば、公式の PHP_INI_PERDIR
変更可能性モードがあるにもかかわらず、この方法で always_populate_raw_post_data
を変更することはできません。これと同じことは、PHP_INI_SYSTEM
変更可能性モードがあるどのディレクティブにも当てはまります。
この場合、PHP の FastCGI Process Manager 向けのカスタム設定ファイルインクルードを使用して、PHP 向けの追加設定を起動時に渡すことができます。そのためには、PHP マニュアルのここで説明されているように、php_value
および php_flag
ディレクティブを使用します。
たとえば、php://input
にアクセスするときに PHP 5.6 の非推奨勧告を避けるために always_poplate_raw_post_data
を -1
に設定するには、次の内容を含む fpm_custom.conf
ファイルをアプリケーションに追加します。
php_value[always_populate_raw_post_data]=-1
そのような新しいカスタム FPM 設定インクルードを作成したら、ブートスクリプトの -F
オプションを使用して、この設定で起動するようアプリケーションに指示できます。上記の例では、Procfile
を次のように変更して、その設定ファイルを使用します (ドキュメントルートがサブディレクトリ public/
であると想定)。
web: heroku-php-nginx -F fpm_custom.conf public/
PHP-FPM 設定
php.ini
に固有の設定のための php_value
および php_flag
に加えて、その設定ファイルではプールに固有の PHP-FPM 設定ディレクティブがどれも有効であるため、それを使用して PHP-FPM の動作を微調整できます。
PHP-FPM 設定ディレクティブが正しくない場合、アプリケーションの動作停止や予期しない動作が発生しやすいため、使用には注意してください。
たとえば、request_slowlog_timeout
ディレクティブを使用すると、所定の秒数よりも実行時間が長いリクエストをログに記録するよう PHP-FPM に指示できます。この場合、リクエストに関する情報がバックトレースを含めて heroku logs
に出力されます。
request_slowlog_timeout = 1s
request_slowlog_timeout
のデフォルト値は 3s
です。