Heroku での PHP の動作
最終更新日 2025年03月17日(月)
Heroku プラットフォームでは、デプロイされた PHP アプリケーションの処理に PHP buildpack を使用します。以下では、PHP アプリに対する Heroku の動作と、アプリを認識、実行、ビルドする方法を説明します。
自動検出
Heroku の PHP サポートは、ルートディレクトリに composer.json
という名前のファイルのあるアプリケーションに適用されます。アプリケーションに Composer 依存関係がない場合でも、PHP アプリケーションとして認識されるために少なくとも空 ({}
) の composer.json
を含んでいなければなりません。
Heroku は PHP アプリケーションを認識すると、それに応じてプッシュ中に応答します。
$ git push heroku main
-----> PHP app detected
…
composer.json
があらゆる種類の依存関係を require
セクションで指定すると、composer update
を実行することによって対応する composer.lock
が生成されますが、リポジトリにもコミットされなければなりません。そうしないと、プッシュは拒否されます。これにより、Heroku がインストールする依存関係が他のあらゆる環境の依存関係と同じになります。詳細な説明は、PHP デプロイガイドの「依存関係の管理」セクションを参照してください。
PHP ランタイム
Heroku では、公式 PHP ランタイムを使用してご使用のアプリケーションを実行できます。PHP ランタイムを指定する方法についての詳細は、該当する Dev Center の記事を参照してください。
ランタイムの設定
すべての PHP ランタイムがそれぞれのリリースの php.ini-production
ファイルをベース php.ini
設定として使用します。
上記にもかかわらず、次の INI ディレクティブは Heroku 固有の値に設定されています。
date.timezone
をUTC
に設定error_reporting
を以下に設定E_ALL & ~E_STRICT
(8.4 より前の PHP バージョン)E_ALL
(PHP 8.4 以降)
expose_php
をOff
に設定session.sid_length
を32
に設定 (PHP バージョン 7.3 ~ 8.3)short_open_tag
をOn
に設定user_ini.cache_ttl
を86400
に設定variables_order
をEGPCS
に設定
さらに、PHP ランタイムでは常に OPcache が有効になっているためパフォーマンスが向上しており、次の設定変更が Heroku の dyno の固有特性に合わせて最適化されています。
opcache.enable_cli
を1
に設定opcache.validate_timestamps
を0
に設定
PHP CLI
php
CLI 実行可能ファイルの memory_limit
PHP INI ディレクティブは、完全に利用可能な dyno メモリにデフォルトで設定されます。たとえば、php
コマンドを使用する Worker dyno は、デフォルトの PHP INI の値 128M
の代わりにこのメモリ制限を使用します。
デフォルトランタイム
composer.json
を使用しないアプリケーション、またはどの依存パッケージにも composer.lock
に php
パッケージの要件が含まれていないアプリケーションは、そのアプリのスタックで使用できる最新バージョンの PHP を取得します。
アップグレード
ランタイムバージョン依存関係を宣言していないアプリケーションをデプロイすると、当時の最新バージョンの PHP が使用されます。ご使用のアプリケーションは、より新しいバージョンの PHP がある場合、次のデプロイ時に自動的にアップグレードされます。
ご使用のアプリケーションがランタイムバージョン依存関係を宣言している場合、バージョン制約に適合する最新のバージョンがインストールで選択されます。
ランタイムの動作
$PATH
環境変数には、アプリケーションがランタイム時に機能するために必要なすべてのパスが含まれています。Composer bin-dir
は便宜上 $PATH
に付け加えられています。
PHP-FPM 設定
PHP-FPM は、dyno サイズと設定された PHP memory_limit
に基づいて、適切な数の Worker プロセスを自動的に生成するよう設定されます。詳細は、「PHP アプリケーションの並列性の最適化」を参照してください。
タイムアウト
リクエストが Heroku ルーターのリクエストタイムアウトに達した場合、PHP-FPM プロセスは、外部タイムアウトなどが発生するまで実行を継続することがあります。これにより PHP-FPM プロセスが拘束されることがあり、他の受信リクエストに応答しなくなる可能性があります。
PHP 7.4 以降を使用するアプリケーションの場合、PHP-FPM はデフォルトで次の動作を行います。
- 3 秒 (
request_slowlog_timeout
ディレクティブ) 以上かかっているリクエストのバックトレースをログに記録する - 実行時間が 30 秒 (
request_terminate_timeout
ディレクティブ) を超過したことによりタイムアウトした可能性があるリクエストを終了する
PHP-FPM の設定を調節して、 次の (あるいはその他の) 設定を変更することができます。
Composer 設定
Composer の次の設定は、便宜上、環境変数を使用して自動的に設定されます。
$COMPOSER_MEMORY_LIMIT
はデフォルトで、利用可能な dyno メモリに設定されます。$COMPOSER_MIRROR_PATH_REPOS
はデフォルトで1
に設定されます。$COMPOSER_NO_INTERACTION
はデフォルトで1
に設定されます。$COMPOSER_PROCESS_TIMEOUT
はデフォルトで0
に設定されます。
設定のカスタマイズ
PHP
PHP マニュアルの指示に従ってプロジェクトに置かれたあらゆる .user.ini
ファイルが、メイン php.ini
の後にロードされます。これらを使用して、PHP_INI_ALL
、PHP_INI_USER
および PHP_INI_PERDIR
のコンテキストで認められたあらゆるディレクティブを設定できます。
この詳細や PHP ランタイムの設定をカスタマイズする他の方法については、該当する Dev Center の記事を参照してください。
ビルド動作
依存関係のインストール
以下のコマンドはデプロイ時に実行されて、依存関係を解決します。ただし composer.json
が空で composer.lock
が存在しない場合を除きます。
$ composer install --no-dev --prefer-dist --optimize-autoloader --no-interaction
Heroku が開発依存関係を composer.json
の require-dev
セクションからインストールすることはありません。ただし、require-dev
セクションに PHP ランタイムバージョン要件が含まれていたり当該の要件を含む依存関係がリストされている場合、composer.json
の require
セクションに PHP ランタイムバージョン要件も含まれているか、当該の要件を含む依存関係もリストされていなければなりません。これは、Heroku がデフォルトの PHP ランタイムバージョンを選ばないようにすることで他の環境 (require-dev
依存関係を含む) がインストールするものと競合しないようにするためです。
インストールしたバージョンの Composer は出力されるため、インストールが開始される前に参照できます。ビルドは、アプリケーションの composer.lock
と互換性がある、できるだけ最新の Composer バージョン (1.x、2.2.x LTS、または 2.3+) を使用して実行されます。Composer のそれぞれのバージョンは、コマンド名 composer
でアプリの実行時に $PATH
で参照できます。
後続のデプロイでのパッケージのインストールを高速化するために、アプリケーションの Composer キャッシュディレクトリはビルド間で保持されます。
カスタムコンパイルステップ
標準の post-install-cmd
Composer スクリプト (たとえばアセットコンパイルまたはキャッシュプレウォーム手順) の一部ではない、ビルド中に追加のコンパイルステップを実行するアプリケーションは、次のコマンドを使用して compile
カスタムコマンド (composer.json
にある場合) が実行されます。
$ composer compile --no-dev --no-interaction
composer.json で定義されているそうしたカスタムスクリプトコマンドはいずれも、1 つの文字列か、実行する複数のコマンドの配列です。例:
{
"scripts": {
"compile": [
"@php app/console assetic:dump --env=prod --no-debug",
"MyVendor\\MyClass::postDeployComposerCallback"
]
}
}
php
または composer
をいずれかの Composer スクリプトで実行する必要がある場合、常に @php
または @composer
の省略表記を使用して実行可能ファイルを参照してください。これにより、すべての環境で常に正しい PHP または Composer 実行可能ファイルが呼び出され、すべての Composer 設定 (正しい PHP memory_limit
を含む) が確実に適用されます。
Composer の bin-dir
がコマンド実行中に $PATH
の上にプッシュされているので、依存関係によりインストールされたバイナリが、スクリプトを記述するとき、vendor/bin/
または同様の接頭辞を使用しなくても、CLI コマンドとして容易にアクセス可能になります。
プライベートリポジトリ
Private Packagist のようなプライベートリポジトリや、認証を必要とするソース (プライベートの GitHub リポジトリなど) からのパッケージを使用するには、Composer を認証詳細 (一般にはプロバイダーまたはサービスにより生成されたトークン) と共に指定する必要があります。
開発マシンで、これらは一般に Composer により auth.json
に保存されます。しかし Heroku では、このような秘密情報は環境変数として保存されます。COMPOSER_AUTH
環境変数は自動的に Composer から読み込まれます。その JSON 構造は auth.json
と同じです。
以下のエントリは、JSON ドキュメントで最上位の鍵として認められています。
各エントリにはドメインのハッシュが鍵として、認証詳細が値として含まれます。認証詳細構造は、上記の各ソースに固有のものであり、ドキュメントで説明されています。
GitHub Enterprise や Self-Managed version of GitLab を使用しているときは、github-domains
または gitlab-domains
設定オプションをプロジェクトの composer.json
内で設定することも忘れないでください。
たとえば、Private Packagist アカウントの認証詳細を保管するには、COMPOSER_AUTH
変数を heroku config:set
と http-basic
詳細を使用して設定します (「YOURTOKEN」を生成された実際のトークン Private Packagist に置き換えます)。
$ heroku config:set COMPOSER_AUTH='{"http-basic":{"repo.packagist.com":{"username":"token","password":"YOURTOKEN"}}}'
もう 1 つの例を挙げると、プライベート GitHub リポジトリのコードを Composer 依存関係として使用しているとき、個人用の OAuth トークンを認証で設定できます。新しいトークンを作成した後で、それを Heroku で設定できます (「YOURTOKEN」を生成された実際のトークン GitHub に置き換えます)。
$ heroku config:set COMPOSER_AUTH='{"github-oauth":{"github.com":"YOURTOKEN"}}'
composer.json
の中のプライベートリポジトリ URL は https://
プロトコルを使用しなければなりません。git://
プロトコルを使用すると Composer が OAuth トークンを認証で使用できなくなります。
複数の認証詳細セットを組み合わせて 1 つのドキュメントにして、たとえばプライベート GitHub リポジトリとプライベート BitBucket リポジトリの両方を使用することもできます。
$ heroku config:set COMPOSER_AUTH='{
"github-oauth": {"github.com": "YOURTOKEN"},
"bitbucket-oauth": {"bitbucket.org": {
"consumer-key": "YOURKEY", "consumer-secret": "YOURSECRET"}
}
}'
上記の例のように Heroku で環境変数を設定するとき引用符内で改行を使用できます。しかし、heroku config:set
コマンドを実行するとき引用が正しくなるようにしなければなりません。
カスタマーサポート
Heroku サポートチャネルのいずれかを通じて問題を報告できます。