콘텐츠로 건너뛰기

Nginx의 client_max_body_size를 올바르게 설정하는 방법 | 업로드 제한 문제 해결

카테고리: Nginx·서버 설정
이 기사는 현재 일본어로만 제공됩니다. 번역본은 순차적으로 공개될 예정입니다.

Nginx에서 파일 업로드를 구현할 때, 「작은 파일은 전송되지만 큰 파일을 보내면 413 오류가 발생한다」는 문제는 매우 자주 마주칩니다. 그 원인은 거의 대부분 <code>client_max_body_size</code> 설정 부족입니다. 그러나 Nginx 설정만 수정해도 해결되지 않는 경우가 많으며, PHP의 <code>upload_max_filesize</code>와 <code>post_max_size</code>, 나아가 타임아웃 설정까지 포함한 총체적인 이해가 필요합니다. 본 문서에서는 업로드 제한과 관련된 모든 설정 항목을 체계적으로 설명합니다.

client_max_body_size 10m 5 MB POST 10 MB POST 20 MB POST nginx limit: 10 MB 200 OK 200 OK 413 Too Large 제한을 초과한 요청은 업스트림에 도달하기 전에 413으로 거부됨
그림: client_max_body_size에 의한 허용/거부 판정

client_max_body_size의 기본값과 역할

Nginx에는 클라이언트로부터의 요청 본문 최대 크기를 제한하는 <code>client_max_body_size</code> 지시문이 있습니다. 기본값은 <code>1m</code> (1 MiB)입니다. 이 제한을 초과하는 요청은 즉시 <code>413 Request Entity Too Large</code> 오류로 거부됩니다.

기본값이 1m으로 매우 작기 때문에 이미지 한 장이나 PDF를 업로드해도 금방 상한에 도달합니다. 실제 프로덕션 환경에서는 용도에 따라 이 값을 적절히 높여야 합니다.

설정 장소: http / server / location의 차이

<code>client_max_body_size</code>는 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;
        }
    }
}

업로드 전용 엔드포인트만 큰 값을 설정하고 나머지는 작은 값으로 유지하는 것이 보안 측면에서 바람직한 접근법입니다. <code>0</code>을 지정하여 무제한으로 할 수 있지만, DoS 공격 위험이 증가하므로 권장하지 않습니다.

413 Request Entity Too Large 에러의 원인과 해결

413 에러가 발생하는 원인과 대처법을 정리합니다.

원인 확인 항목 대처 방법
Nginx 제한 초과 nginx.conf의 <code>client_max_body_size</code> 값 올리기
PHP 제한 초과 php.ini의 <code>upload_max_filesize</code> 값 올리기
POST 본문 전체 제한 초과 php.ini의 <code>post_max_size</code> upload_max_filesize 보다 크게 설정
리버스 프록시 제한 업스트림 Nginx 또는 로드 밸런서 설정 각 단계의 프록시 확인

Nginx 설정을 변경한 후에는 반드시 리로드가 필요합니다.

# 設定の文法チェック
nginx -t

# 設定のリロード(サービス停止なし)
nginx -s reload

# または systemd 経由
systemctl reload nginx

PHP의 upload_max_filesize / post_max_size와의 관계

Nginx의 <code>client_max_body_size</code>를 높이는 것만으로는 충분하지 않습니다. 백엔드가 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까지 도달하지 않습니다
  • <code>post_max_size</code>는 복수 파일 업로드와 파일 이외의 폼 필드도 포함한 POST 바디 전체의 크기 제한

proxy_read_timeout / proxy_send_timeout 의 중요성

대용량 파일 업로드 시에는 타임아웃 설정이 중요합니다. 기본 <code>proxy_read_timeout</code>은 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 설정에서 <code>client_max_body_size</code>의 값을 확인하려면, <code>nginx -T</code>로 모든 설정을 전개한 후 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"

일반적인 설정 오류 및 해결 방법

  • <strong>단위 오류</strong>: <code>client_max_body_size 100</code>은 바이트로 지정됩니다. <code>100m</code>처럼 반드시 단위를 붙이세요
  • <strong>계층 간과</strong>: location 블록 내에서 상위에 있는 server 블록이나 http 블록이 적용되고 있는 경우
  • <strong>리로드 잊음</strong>: 설정 파일을 변경해도 <code>nginx -s reload</code>를 실행하지 않으면 적용되지 않습니다
  • <strong>여러 server 블록</strong>: include로 읽어들인 다른 conf.d 파일이 충돌하고 있습니다
  • <strong>PHP와의 불일치</strong>: Nginx를 올려도 PHP의 <code>upload_max_filesize</code>가 낮은 まま이면 413 외의 오류 발생

이 기사에서 사용할 수 있는 테스트 파일 (무료)

  • → <a href="/ja/files/threshold/" class="text-primary-600 dark:text-primary-400 hover:underline">경계값 테스트 파일 목록</a> — client_max_body_size 설정값 전후의 파일로 오류 재현
  • → <a href="/ja/files/images/png/" class="text-primary-600 dark:text-primary-400 hover:underline">PNG 테스트 이미지 목록</a> — 다양한 크기의 PNG로 Nginx 제한 확인

관련 기사

  • → <a href="/ja/blog/how-to-test-upload-limit/" class="text-primary-600 dark:text-primary-400 hover:underline">파일 업로드 제한을 올바르게 테스트하는 방법</a>
  • → <a href="/ja/blog/multipart-form-data-overhead/" class="text-primary-600 dark:text-primary-400 hover:underline">multipart/form-data 의 오버헤드를 정확하게 계산하기</a>
  • → <a href="/ja/blog/mb-vs-mib-file-size/" class="text-primary-600 dark:text-primary-400 hover:underline">MB 와 MiB 의 차이|파일 크기 단위의 올바른 이해</a>

자주 묻는 질문

Nginx의 client_max_body_size 기본값은 무엇인가요?

기본값은 1m(1메가바이트)입니다. 이를 초과하는 요청은 413 Request Entity Too Large 오류가 발생합니다.

client_max_body_size는 어디에 설정해야 할까?

<code>http</code>, <code>server</code>, 또는 <code>location</code> 블록에서 설정할 수 있습니다. 특정 엔드포인트만 변경하고 싶으면 <code>location</code> 블록에 작성하세요.

Nginx와 PHP 업로드 설정의 관계는?

Nginx는 요청이 PHP에 도달하기 전에 client_max_body_size로 확인합니다. PHP 측의 upload_max_filesize와 post_max_size도 함께 설정해야 합니다.