php_fastcgi
php-fpmなどのPHP FastCGIサーバーにリクエストをプロキシする、独自性の強いディレクティブです。
Caddyのreverse_proxy
は、あらゆるFastCGIアプリケーションを処理できますが、このディレクティブは特にPHPアプリ向けに調整されています。このディレクティブは便利なショートカットであり、より長い設定を置き換えるものです。
このディレクティブは、サイトルートにあるindex.php
がルーターとして機能することを想定しています。そうでない場合は、try_files
サブディレクティブを再設定してデフォルトのリライト動作を変更するか、展開形をベースとして、必要に応じてカスタマイズしてください。
以下に示すサブディレクティブに加えて、このディレクティブはreverse_proxy
のすべてのサブディレクティブもサポートしています。たとえば、負荷分散やヘルスチェックを有効にすることができます。
ほとんどの現代的なPHPアプリは、追加のサブディレクティブやカスタマイズなしで正常に動作します。サブディレクティブは、通常、特定の例外的なケースやレガシーPHPアプリでのみ使用されます。
構文
php_fastcgi [<matcher>] <php-fpm_gateways...> {
root <path>
split <substrings...>
index <filename>|off
try_files <files...>
env [<key> <value>]
resolve_root_symlink
capture_stderr
dial_timeout <duration>
read_timeout <duration>
write_timeout <duration>
<any other reverse_proxy subdirectives...>
}
-
<php-fpm_gateways...> は、FastCGIサーバーのアドレスです。通常、TCPソケットまたはunixソケットファイルのいずれかです。
-
root サイトのルートフォルダーを設定します。
php_fastcgi
と組み合わせてroot
ディレクティブを常に使用することをお勧めしますが、PHP-FPMアップストリームがCaddyとは異なるルートを使用している場合(例を参照)、これをオーバーライドすると役立つことがあります。使用されている場合はroot
ディレクティブの値にデフォルト設定され、そうでない場合はCaddyの現在の作業ディレクトリにデフォルト設定されます。 -
split URIを2つの部分に分割するためのサブストリングを設定します。最初に一致したサブストリングを使用して、「パス情報」をパスから分割します。最初の部分は一致したサブストリングが接尾辞として付加され、実際のリソース(CGIスクリプト)名として想定されます。2番目の部分は、CGIスクリプトで使用されるPATH_INFOに設定されます。デフォルト:
.php
-
index ディレクトリのインデックスファイルとして扱うファイル名を指定します。これは、展開形のファイルマッチャーに影響します。デフォルト:
index.php
。一致するファイルが見つからない場合にindex.php
へのリライトフォールバックを無効にするには、off
に設定できます。 -
try_files デフォルトのtry-filesリライトのオーバーライドを指定します。詳細については、
try_files
ディレクティブを参照してください。デフォルト:{path} {path}/index.php index.php
。 -
env 指定された値に環境変数を追加します。複数の環境変数に対して複数回指定できます。デフォルトでは、すべての関連するFastCGI環境変数(HTTPヘッダーを含む)はすでに設定されていますが、必要に応じて変数を追加またはオーバーライドできます。
-
resolve_root_symlink
root
ディレクトリがシンボリックリンク(symlink)である場合、これを有効にすると、その実際の値に解決されます。これは、シンボリックリンクを別のディレクトリ内の新しいバージョンを指すように切り替えるだけで済む、デプロイ戦略として使用されることがあります。システム呼び出しの繰り返しを避けるため、デフォルトでは無効になっています。 -
capture_stderr アップストリームのfastcgiサーバーから
stderr
で送信されたメッセージのキャプチャとロギングを有効にします。ロギングは、デフォルトでWARN
レベルで行われます。レスポンスのステータスが4xx
または5xx
の場合、代わりにERROR
レベルが使用されます。デフォルトでは、stderr
は無視されます。 -
dial_timeout アップストリームソケットへの接続時に待機する時間を設定する、期間値です。デフォルト:
3s
。 -
read_timeout FastCGIアップストリームからの読み取り時に待機する時間を設定する、期間値です。デフォルト: タイムアウトなし。
-
write_timeout FastCGIアップストリームへの送信時に待機する時間を設定する、期間値です。デフォルト: タイムアウトなし。
このディレクティブはリバースプロキシに対する独自性の強いラッパーであるため、reverse_proxy
のサブディレクティブを使用してカスタマイズできます。
展開形
php_fastcgi
ディレクティブ(サブディレクティブなし)は、次の設定と同じです。ほとんどの現代的なPHPアプリはこのプリセットでうまく機能します。そうでない場合は、php_fastcgi
ショートカットを使用する代わりに、必要に応じてこのプリセットを借用してカスタマイズしてください。
route {
# Add trailing slash for directory requests
@canonicalPath {
file {path}/index.php
not path */
}
redir @canonicalPath {http.request.orig_uri.path}/ 308
# If the requested file does not exist, try index files
@indexFiles file {
try_files {path} {path}/index.php index.php
split_path .php
}
rewrite @indexFiles {file_match.relative}
# Proxy PHP files to the FastCGI responder
@phpFiles path *.php
reverse_proxy @phpFiles <php-fpm_gateway> {
transport fastcgi {
split .php
}
}
}
説明
-
最初のセクションは、リクエストパスの正規化を扱います。目標は、ディスク上のディレクトリをターゲットとするリクエストに、リクエストパスに末尾のスラッシュ
/
が追加されるようにし、そのディレクトリへのリクエストに対して単一のURLのみが有効になるようにすることです。これは、スラッシュで終わらないリクエストであり、ディスク上に
index.php
ファイルを含むディレクトリにマップされるリクエストのみを照合するリクエストマッチャーを使用することで実行されます。一致した場合、末尾のスラッシュを追加してHTTP 308リダイレクトを実行します。たとえば、ディスク上に/foo/index.php
が存在する場合、パスが/foo
のリクエストを/foo/
にリダイレクトします(/
を追加して、ディレクトリへのパスを正規化します)。 -
次のセクションでは、一致するファイルがディスク上に存在するかどうかに基づいてパスリライトを実行します。これにより、リクエストパスに
.php
が含まれている場合、.php
以降のパスの部分を記憶するという副作用もあります。これは、CaddyがFastCGI環境変数を正しく設定するために重要です。-
最初に、
{path}
がディスク上に存在するファイルであるかどうかを確認します。存在する場合は、そのパスにリライトします。これにより、本質的に残りの処理を短絡し、ディスク上に存在するファイルへのリクエストが、それ以外の場合はリライトされないようにします(以下の次のステップを参照)。たとえば、ディスク上に/js/app.js
ファイルがある場合、そのパスへのリクエストは同じままになります。 -
次に、
{path}/index.php
がディスク上に存在するファイルであるかどうかを確認します。存在する場合は、そのパスにリライトします。/foo/
のようなディレクトリへのリクエストの場合、/foo//index.php
(/foo/index.php
に正規化されます)を検索し、存在する場合はそのパスにリライトします。この動作は、Webルートのサブディレクトリで別のPHPアプリを実行している場合に役立つことがあります。 -
最後に、
index.php
が存在する場合(最新のPHPアプリではほとんどの場合存在する必要があります)、それにリライトします。これにより、PHPアプリは、ディスク上のファイルにマップされないパスに対するリクエストを、index.php
スクリプトをエントリポイントとして使用して処理できます。
-
-
そして最後に、最後のセクションでは、PHPコードを実際に実行するために、PHP FastCGI(またはPHP-FPM)サービスにリクエストを実際にプロキシします。リクエストマッチャーは
.php
で終わるリクエストのみに一致するため、PHPスクリプトではなく、ディスク上に存在するファイルは、このディレクティブでは処理されず、フォールスルーされます。
php_fastcgi
ディレクティブだけでは通常不十分です。ディスク上のファイルの場所を設定するためには、ほとんどの場合、root
ディレクティブ(最新のPHPアプリでは、/var/www/html/public
になる可能性があります。ここで、public
ディレクトリにはindex.php
が含まれています)と、このディレクティブで処理されず、フォールスルーした静的ファイル(JS、CSS、画像など)を提供するためのfile_server
ディレクティブと組み合わせて使用する必要があります。
例
127.0.0.1:9000
でリッスンしているFastCGIレスポンダにすべてのPHPリクエストをプロキシする
php_fastcgi 127.0.0.1:9000
同じですが、/blog/
以下のリクエストのみに適用
php_fastcgi /blog/* localhost:9000
unixソケット経由でリッスンしているPHP-FPMを使用する場合
php_fastcgi unix//run/php/php8.2-fpm.sock
root
ディレクティブは、ほとんどの場合、PHPスクリプトを含むディレクトリを指定するために使用され、file_server
ディレクティブは静的ファイルを提供するために使用されます
example.com {
root * /var/www/html/public
php_fastcgi 127.0.0.1:9000
file_server
}
Caddyで複数のPHPアプリを提供する場合、各アプリのWebルートは、Caddyが静的ファイルを個別に読み取り、提供し、PHPファイルが存在するかどうかを検出できるように、異なっている必要があります。
Dockerを使用している場合、多くの場合、PHP-FPMコンテナは同じルートにファイルをマウントします。その場合、解決策は、Caddyコンテナに異なるディレクトリにファイルをマウントし、root
サブディレクティブを使用して各コンテナのルートを設定することです
app1.example.com {
root * /srv/app1/public
php_fastcgi app1:9000 {
root /var/www/html/public
}
file_server
}
app2.example.com {
root * /srv/app2/public
php_fastcgi app2:9000 {
root /var/www/html/public
}
file_server
}
index.php
をエントリポイントとして使用しないPHPサイトの場合、代わりに404
エラーを発生させるようにフォールバックできます。エラーは、handle_errors
ディレクティブでキャッチして処理できます
example.com {
php_fastcgi localhost:9000 {
try_files {path} {path}/index.php =404
}
handle_errors {
respond "{err.status_code} {err.status_text}"
}
}