Nginxのclient_max_body_sizeを正しく設定する方法|アップロード上限のトラブル解決
Nginxでファイルアップロードを実装したとき、「小さいファイルは送れるのに大きいファイルを送ると 413 エラーになる」という問題は非常によく遭遇します。その原因のほとんどは client_max_body_size の設定不足です。しかし、Nginxの設定だけ直しても解決しないケースも多く、PHPの upload_max_filesize や post_max_size、さらにはタイムアウト設定まで含めたトータルな理解が必要です。本記事では、アップロード上限に関わるすべての設定項目を体系的に解説します。
client_max_body_size のデフォルト値と役割
Nginxには client_max_body_size というディレクティブがあり、クライアントからのリクエストボディの最大サイズを制限します。デフォルト値は 1m(1 MiB)です。これを超えるリクエストは即座に 413 Request Entity Too Large エラーとして拒否されます。
デフォルトが 1m と非常に小さいため、画像1枚やPDFのアップロードでもすぐに上限に達してしまいます。実際のプロダクション環境では用途に応じてこの値を適切に引き上げる必要があります。
設定場所:http / server / location の違い
client_max_body_size は Nginx の設定階層(http / server / location)のどこにでも記述できます。より詳細なスコープの設定が優先されます。
# http ブロック(全サーバー共通)
http {
client_max_body_size 10m;
server {
listen 80;
server_name example.com;
# server ブロック(このバーチャルホスト全体)
client_max_body_size 50m;
location /upload {
# location ブロック(このパスのみ)
# より大きなファイルを許可したい場合
client_max_body_size 200m;
proxy_pass http://app;
}
location /api {
# APIエンドポイントはデフォルト(1m)のままにする例
client_max_body_size 1m;
}
}
}
アップロード専用のエンドポイントだけ大きい値を設定し、他は小さい値に抑えるのがセキュリティ上の好ましいアプローチです。無制限にしたい場合は 0 を指定しますが、DoS攻撃のリスクが増すため推奨しません。
413 Request Entity Too Large エラーの原因と解決
413 エラーが発生する原因と対処法を整理します。
| 原因 | 確認箇所 | 対処法 |
|---|---|---|
| Nginx の制限超過 | nginx.conf の client_max_body_size |
値を引き上げる |
| PHP の制限超過 | php.ini の upload_max_filesize |
値を引き上げる |
| POSTボディ全体の制限超過 | php.ini の post_max_size |
upload_max_filesize より大きくする |
| リバースプロキシの制限 | 上流のNginxやロードバランサー設定 | 各段のプロキシを確認する |
Nginx の設定変更後は必ずリロードが必要です。
# 設定の文法チェック
nginx -t
# 設定のリロード(サービス停止なし)
nginx -s reload
# または systemd 経由
systemctl reload nginx
PHPの upload_max_filesize / post_max_size との関係
Nginx の client_max_body_size を引き上げただけでは不十分です。バックエンドが PHP の場合、PHPレベルでも独立した制限があります。この3つの設定がすべて適切な値になって初めてアップロードが成功します。
; php.ini の設定
; 1ファイルあたりの上限
upload_max_filesize = 100M
; POSTリクエスト全体の上限(upload_max_filesize より大きくする)
; multipart/form-data のオーバーヘッド分を見込んで多めに設定
post_max_size = 110M
; メモリ上限(post_max_size より大きくする)
memory_limit = 256M
; アップロード処理の実行時間(大容量ファイル用に延ばす)
max_execution_time = 300
max_input_time = 300
重要な設定値の関係は以下のとおりです。
- client_max_body_size(Nginx) ≥ post_max_size(PHP) ≥ upload_max_filesize(PHP)
- Nginx がリクエストを拒否してしまうと、PHP まで処理が届かない
post_max_sizeは複数ファイルのアップロードや、ファイル以外のフォームフィールドも含んだ POSTボディ全体のサイズ制限
proxy_read_timeout / proxy_send_timeout の重要性
大容量ファイルのアップロードでは、タイムアウト設定も重要です。デフォルトの proxy_read_timeout は 60 秒で、アップロードに時間がかかると処理が中断されてしまいます。
location /upload {
client_max_body_size 500m;
proxy_pass http://app_backend;
# バックエンドからのレスポンス待機時間
# 大容量ファイルの処理には長めに設定
proxy_read_timeout 600s;
# クライアントへのデータ送信待機時間
proxy_send_timeout 600s;
# バックエンドへの接続タイムアウト
proxy_connect_timeout 60s;
# クライアントのリクエストボディ受信タイムアウト
# 2回の連続した読み取り操作の間の時間
client_body_timeout 120s;
}
アップロード用エンドポイントと通常のAPIエンドポイントでタイムアウト値を分けて設定することが推奨されます。
Dockerでの設定(nginx.conf マウント)
Docker 環境では、カスタムの nginx.conf または conf.d ファイルをコンテナにマウントして設定を反映します。
# Dockerfile でのカスタム設定追加
FROM nginx:alpine
# カスタム設定ファイルをコピー
COPY ./nginx/conf.d/upload.conf /etc/nginx/conf.d/upload.conf
# デフォルト設定を完全に置き換える場合
# COPY ./nginx/nginx.conf /etc/nginx/nginx.conf
# docker-compose.yml でのボリュームマウント
version: '3.8'
services:
nginx:
image: nginx:alpine
volumes:
# ディレクトリごとマウント(変更が即反映される)
- ./nginx/conf.d:/etc/nginx/conf.d
# または特定ファイルだけマウント
# - ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro
ports:
- "80:80"
# nginx/conf.d/upload.conf
server {
listen 80;
server_name localhost;
# グローバルのアップロード上限
client_max_body_size 100m;
location / {
proxy_pass http://app:9000;
proxy_read_timeout 300s;
proxy_send_timeout 300s;
}
location /upload {
client_max_body_size 500m;
proxy_pass http://app:9000;
proxy_read_timeout 600s;
proxy_send_timeout 600s;
}
}
設定確認コマンド
現在の Nginx 設定で client_max_body_size がどの値になっているか確認するには、nginx -T で全設定を展開してから grep するのが便利です。
# 全設定を展開して client_max_body_size を検索
nginx -T | grep -i body_size
# 出力例:
# client_max_body_size 1m; ← デフォルト(http ブロック)
# client_max_body_size 100m; ← カスタム設定(server ブロック)
# 設定ファイルのパスも確認
nginx -T | grep "# configuration"
# 特定の設定ファイルだけチェック
nginx -t -c /etc/nginx/nginx.conf
# 現在読み込まれている設定のダンプ
nginx -T 2>/dev/null | grep -A1 "client_max"
よくある設定ミスと対処法
- 単位の誤り:
client_max_body_size 100はバイト指定になる。100mのように単位を必ず付ける - 階層の見落とし:location ブロック内で上書きしているつもりが、上位の server ブロックや http ブロックが効いているケース
- リロード忘れ:設定ファイルを変更しても
nginx -s reloadしないと反映されない - 複数 server ブロック:include で読み込まれる別の conf.d ファイルが競合している
- PHPとの不一致:Nginx を上げても PHP の
upload_max_filesizeが低いままで 413 以外のエラーが出る
この記事で使えるテストファイル(無料)
- → 境界値テスト用ファイル一覧 — client_max_body_size の設定値前後のファイルでエラーを再現
- → PNGテスト画像一覧 — 様々なサイズの PNG で Nginx 制限を確認