🍙
初めてのNginx × PHP-FPM × Docker構成:default.confの書き方とCORS対応
Docker Compose 環境での Nginx + PHP-FPM 構成:nginx/default.conf の基本設定と CORS対応のポイント
基本設定
listen 80;
server_name localhost;
root /app/public;
index index.php index.html;
解説:
ディレクティブ | 説明 |
---|---|
listen 80; |
ポート80(HTTP)で接続を受け付ける |
server_name localhost; |
ホスト名が localhost のリクエストを処理対象にする |
root /app/public; |
Webルートディレクトリを /app/public に指定(Dockerコンテナ内のパス) |
index index.php index.html; |
ディレクトリアクセス時の優先ファイル順序 |
location / の設定: 静的ルーティングとCORS対応
location / {
# CORS対応
add_header 'Access-Control-Allow-Origin' * always;
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS, PUT, DELETE' always;
add_header 'Access-Control-Allow-Headers' 'Content-Type, Authorization, uid' always;
# プリフライト対応
if ($request_method = OPTIONS) {
return 204;
}
try_files $uri $uri/ /index.php?$query_string;
}
解説:
-
CORS対応:
- Nginx では
location
ごとにadd_header
を設定する必要があるため、/
と~ \.php$
の両方にヘッダーを記述しています。 - フロントエンドが別ドメイン(例:React, Vue)からAPIを呼ぶ場合に必要。
-
add_header
ディレクティブは、HTTPレスポンスに任意のヘッダーを追加するための設定です。 -
always
を付けることで、204 No Content
や4xx
5xx
などのエラーレスポンス時にもヘッダーが必ず付加されるようになります。 - 例として、以下のようなCORS用レスポンスヘッダーを追加できます:
Access-Control-Allow-Origin: * Access-Control-Allow-Methods: GET, POST, OPTIONS, PUT, DELETE Access-Control-Allow-Headers: Content-Type, Authorization, uid
- セキュリティを意識する場合は、本番環境での
Access-Control-Allow-Origin
を*
(全て) ではなく特定のドメインに限定することが推奨されます。
- Nginx では
-
プリフライト(OPTIONSメソッド)対応:
- クロスオリジン通信の事前確認(プリフライト)リクエストに
204 No Content
を返すことで、ブラウザからのCORSリクエストを正しく完了させます。
- クロスオリジン通信の事前確認(プリフライト)リクエストに
-
try_files ディレクティブ:
try_files $uri $uri/ /index.php?$query_string;
-
$uri
:そのままのリクエストパス(ファイル)を探す -
$uri/
:ディレクトリとして探す - 見つからなければ
index.php
に内部転送 -
/index.php?$query_string
を指定することで、LaravelやSymfonyのようなシングルエントリーポイント型のルーティングをPHP側で行う設計が可能になります。
-
location ~ .php$ の設定: PHPファイルのリクエストをPHP-FPMへ渡す
location ~ \.php$ {
include fastcgi_params;
fastcgi_pass backend-php:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
add_header 'Access-Control-Allow-Origin' * always;
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS, PUT, DELETE' always;
add_header 'Access-Control-Allow-Headers' 'Content-Type, Authorization, uid' always;
}
解説:
設定 | 説明 |
---|---|
location ~ \.php$ |
.php で終わるファイルへのリクエストを対象にする |
include fastcgi_params; |
PHP-FPM に必要な環境変数(共通設定)を読み込む |
fastcgi_pass backend-php:9000; |
PHP-FPM のホスト(Dockerコンテナ名)とポートを指定 |
fastcgi_index index.php; |
ディレクトリ指定時のデフォルトPHPファイル |
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; |
PHPに渡す実行対象ファイルのフルパスを指定します。$document_root は Nginx の設定ファイルで root で指定されたパス(例:/app/public)を指し、$fastcgi_script_name はリクエストされたPHPファイル名(例:/index.php)です。この2つを連結することで、PHP-FPM に正確なスクリプトのパス(例:/app/public/index.php)を渡すことができます。この指定が間違っていると、PHPが実行されず404エラーになることがあります。 |
add_header |
CORS対応のためのヘッダーを付加(フロントエンド連携のため) |
間違い例: fastcgi_param SCRIPT_FILENAME /app/public$fastcgi_script_name;
- このようにハードコーディングしてしまうと、root ディレクティブを変更したときに整合性が取れず、デプロイ環境によって動かなくなる可能性があります。
- $document_root を使うことで、Nginxの設定全体と連動した柔軟な記述が可能になります。
全体のリクエスト処理の流れ
- クライアントからリクエスト(例:/api/register)
- 静的ファイルがあればそれを返す
- なければ index.php に内部転送
- .php にマッチする場合は PHP-FPM に処理を渡す
- レスポンスには CORS ヘッダーが付加される(JSフロント側との連携が円滑に)
補足1:本番環境でのCORS設定の注意点
Access-Control-Allow-Origin の設定について
-
Access-Control-Allow-Origin: *
は開発中には便利ですが、本番環境ではセキュリティ上のリスクがあるため、使用は避けるべきです。 - すべてのオリジンからのアクセスを許可すると、信頼できない外部サイトからの不正リクエストも許容されてしまいます。
- 認証が必要なAPIで
withCredentials: true
を使う場合も*
は使用できないため、以下のように信頼できるドメインを明示的に指定するのが望ましいです。
add_header 'Access-Control-Allow-Origin' 'https://example.com' always;
補足2:PHP-FPMとは?
Nginx は自分で PHP を処理することができません。そのため、PHP の実行は PHP-FPM(FastCGI Process Manager) に委ねます。
PHP-FPM は、リクエストを受けて PHP スクリプトを実行し、その結果を Nginx に返す役割を担います。
Nginx の設定では以下のように指定します:
fastcgi_pass backend-php:9000;
これは、「PHP-FPM が backend-php(Docker コンテナ名)で 9000番ポートで待機しているので、そこに処理を渡す」という意味です。
なぜ PHP-FPM が必要なのか?
- Nginx は静的ファイル(HTML、CSS、画像など)の配信には強いが、PHPのような動的言語の処理はできない
- PHP-FPM が PHP スクリプトの実行を高速かつ非同期でさばいてくれる
- Nginx と分離されているため、スケーラブルかつ柔軟な構成が可能(プロセス管理・ロードバランスもやりやすい)
まとめ
今回紹介した Nginx の設定は、Docker + PHP(FPM)環境で API を構築する際の基本構成になります。
-
listen
やroot
、index
で Web サーバーの基本的な入口を設定し、 -
location /
で CORS やプリフライトリクエストに対応、 -
try_files
で動的ルーティング(index.php へのフォールバック)を実現し、 -
.php
ファイルへのアクセスは PHP-FPM に処理を渡すように構成しました。
このように設定しておくことで、Vue や React などの SPA フロントエンドと連携した堅牢なバックエンド API を構築できます。
Discussion