문제점

nginx + php가 구성된 서버에서, 이미지를 업로드 하려고 하는데 1MB 또는 특정 파일 크기를 넘으면 실패합니다.

전제 조건

  • Nginx 서버 + php
    • 여기서는 php-fpm 7.4 기준으로 설명합니다.

Java Spring에 대해서도 비슷한 경험을 한 적이 있는데 별도의 포스트에서 다루겠습니다.

해결법

Nginx 최대 업로드 크기 설정

Nginx 사이트에 설명되어 있는 설정 키워드 client_max_body_size 지시자를 보면 기본값이 1m, 즉 1MB인 것을 알 수 있습니다.

이 값을 적절한 더 큰 크기로 바꿉니다. 이 설정은 http, server, location 절 모두 가능하므로, 필요한 곳에만 설정이 적용될 수 있도록 위치에 신경써야겠습니다. 불필요하게 크게 하면 큰 파일이 필요 없는 곳에 누군가 대형 파일 업로드를 시도하면 꼼짝없이 트래픽으로 낭비해야 할 것입니다.

client_max_body_size 256m;

이 위치는 원하는 위 3개 선택지(http, server, location) 블록의 적당히 상단에 두면 됩니다.

설정이 되었으면 적용을 위해 nginx의 2종 커맨드를 입력합니다.

$ sudo nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

$ sudo service nginx reload

PHP 파일 업로드 크기 설정

HTTP 서버 역할을 하는 nginx 설정이 되어 있어야 하는 건 당연한 이야기지만, 이에 못지 않게 중요한 게 실제 업로드된 파일을 처리해야 하는, fastcgi로 연결된 php일 것입니다.

nginx에서 location 절로 php를 별도 처리하고 있을텐데, 이 안에 var로 넘겨주는게 php-fpm 설정을 바꿀 필요가 없으며, 여러 가상 서버가 있는 경우에 전역 설정을 바꾸는 부담이 적습니다.

fastcgi_param PHP_VALUE "upload_max_filesize=128M \n post_max_size=256M";

한편, post_max_sizeupload_max_filesize가 불일치한데서 의아함을 느끼실 수도 있는데, 관련 정보를 찾아보니 post_max_size > upload_max_filesize의 관계가 성립하는 듯 합니다. upload_max_filesize는 단일 파일 크기의 최대를 가리키는데 반해, post_max_size는 본문글이나 나머지 첨부파일 등 POST의 모든 내용의 크기를 가리키기 때문이지요.

전체 요청의 크기를 말하기 때문에, nginx의 client_max_body_size = post_max_size > upload_max_filesize가 실질적인 관계가 되지 않을까요? 하지만 실제로는 세 가지 모두 만족하지 않으면 어딘가에서 문제가 발생할 것입니다.

그렇지만 크게 신경 쓸 필요는 없는 것이, 텍스트가 길어봤자 킬로바이트 단위에서 영향을 주는 게 대부분입니다. 일례로 메모장이 64KB 이상의 파일을 열 수 있게 된 것이 불과 윈도우 Vista 이후라고 하니까요. 복수 파일 업로드가 가능한 서비스라면 신경을 크게 써야겠습니다.

location ~ \.php$ { } 내부에 fastcgi_parm이 이미 들어있을텐데, 그 중간 쯤에 넣으면 문제가 없을 것 같습니다.

location ~ \.php$ {
        try_files $uri =404;
        fastcgi_param PHP_VALUE "upload_max_filesize=128M \n post_max_size=256M";
        include fastcgi.conf;
        fastcgi_pass unix:/var/run/php/php7.4-fpm.sock;
    }

예시는 이와 같습니다.

(다른 선택) php-fpm 전역 설정에 넣기

이렇게 하지 않고, php-fpm.conf의 설정값을 변경하면 전역 설정을 바꿀 수 있습니다. 경로는 아마 /etc/php/fpm/7.4/php-fpm.conf 와 같이 버전으로 나뉘어 있을 것입니다.

기본값이 들어있지 않으므로 바로 제일 하단에 정의하면 됩니다.

upload_max_filesize=128M
post_max_size=256M

확인

이제 크기가 1MB 이상인 128MB 이하의 파일도 업로드가 무난히 가능한 것을 확인할 수 있습니다.

2년차 개발자 이진백입니다. 현재 일본에서 웹 프로그래머로 근무중입니다. 주로 Java, Vue (Nuxt), TypeScript 언어를 활용하고 있습니다. 취미로 C#과 Windows Universal Store App을 오래 만져왔고, 개인 서버 운영에도 관심이 많습니다. 최신 이슈를 알기 쉽게 전달해드리도록, 더욱 더 노력하겠습니다.