콘텐츠로 건너뛰기

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

카테고리: Nginx·서버 설정

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

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

기본값이 1m으로 매우 작기 때문에 이미지 한 장이나 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 외의 오류 발생

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

❓ 자주 묻는 질문

Nginx의 client_max_body_size 기본값은?
기본값은 1m(1메가바이트)입니다. 이를 넘는 요청은 413 Request Entity Too Large 에러가 됩니다.
client_max_body_size는 어디에 설정해야 하나요?
http, server, location 블록 중 어디에나 설정할 수 있습니다. 특정 엔드포인트만 바꾸고 싶다면 location 블록에 기술합니다.
Nginx와 PHP의 업로드 설정 관계는?
Nginx의 요청은 PHP에 도달하기 전에 client_max_body_size로 검사됩니다. PHP 측의 upload_max_filesize와 post_max_size도 함께 설정해야 합니다.

자주 묻는 질문

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

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

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

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

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

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