Devops
nginx
블로그 불러오는 중...
문의 보내기
남겨주면 블로그 주인에게 바로 전달돼요.
Devops
nginx
Strapi 를 이용하면서, 미디어 라이브러리에 첨부 파일을 올리는 도중 413 에러가 발생 했다.

응답에 익숙한 nginx 키워드가 보인다. 그래서 nginx 단부터 차례로 풀어 본다.
HTTP 413 은 Payload Too Large (구 Request Entity Too Large) 상태 코드로, 서버가 요청 본문이 허용 한도를 넘었다고 판단 했을 때 반환 한다.
문제는 nginx 의 기본 client_max_body_size 가 1MB 라는 점 이다. 그래서 사진 한 장만 좀 커도 바로 413 이 떨어 진다. Strapi 어드민에서 PDF 나 이미지 몇 장만 올려도 자주 걸리는 이유가 이거다.
$ curl -i -X POST -F "files=@bigfile.pdf" https://api.example.com/api/upload
HTTP/1.1 413 Request Entity Too Large
Server: nginxnginx 설정 파일 (nginx.conf 또는 sites-available/*) 에서 client_max_body_size 를 추가 해 주면 된다.
http, server, location 어느 블록에서든 설정 가능 한데, 하위 블록의 값이 상위 블록을 덮어 쓰는 구조 다. 그래서 한 번에 모든 사이트에 적용 하고 싶으면 http 블록에, 특정 endpoint 에만 풀어 주고 싶으면 location 에 둔다.
http {
# client_max_body_size 20m; # 여기에 설정 가능 (전역)
server {
# client_max_body_size 20m; # 여기에도 설정 가능 (사이트 단위)
location /api/upload {
client_max_body_size 100m; # 업로드 경로만 풀어 주기
...
}
}
}값이 0 이면 제한 해제 — 다만 권장 하지 않는다. 의도치 않게 큰 요청을 받아 낼 수 있어서 메모리 폭발의 빌미가 된다.
설정 후에는 검증과 reload 가 필수다.
$ sudo nginx -t # 문법 검사
$ sudo nginx -s reload # graceful reload쿠버네티스 환경에서 ingress controller 로 nginx 를 사용 한다면, Ingress 리소스에 annotation 으로 풀어 주면 된다.
metadata:
annotations:
nginx.ingress.kubernetes.io/proxy-body-size: "100m"이 annotation 도 기본값이 1m 이라 호스트 nginx 와 같은 함정에 걸린다.
특정 Ingress 만 풀어 주는 게 아니라 클러스터 전체 기본값 을 바꾸고 싶다면, ingress-nginx 의 ConfigMap 을 건드리는 방법도 있다.
apiVersion: v1
kind: ConfigMap
metadata:
name: ingress-nginx-controller
namespace: ingress-nginx
data:
proxy-body-size: "100m"ConfigMap 으로 잡아 두면 새로 만드는 모든 Ingress 가 이 값을 상속 한다. 단, 한 번에 모든 서비스에 영향을 주니 변경 전 영향도부터 체크 하는 편이 안전 하다.
nginx 만 풀었는데 여전히 413 이 떨어 진다면, 그 다음은 애플리케이션 body parser 를 의심 해야 한다. nginx 가 통과 시킨 요청을 그 뒤의 Strapi/Express/NestJS 가 자체 한도로 다시 차단 하는 경우가 종종 있다.
Strapi 의 경우 config/middlewares.js 의 strapi::body 설정이 그 자리다.
// config/middlewares.js
module.exports = [
// ...
{
name: 'strapi::body',
config: {
formLimit: '100mb', // form-urlencoded
jsonLimit: '100mb', // application/json
textLimit: '100mb',
formidable: {
maxFileSize: 100 * 1024 * 1024, // multipart, 100MB
},
},
},
// ...
];Strapi 버전에 따라 키 이름이나 기본값이 다를 수 있다. 본인이 쓰는 버전의 공식 문서 를 기준으로 맞추는 걸 추천.
NestJS 라면 main.ts 에서 app.use(json({ limit: '100mb' })), Express 라면 body-parser 의 limit 옵션을 같이 점검 해야 한다.
client_max_body_size, K8s ingress 면 nginx.ingress.kubernetes.io/proxy-body-size 가 정답.strapi::body, NestJS body-parser).본인 블로그의 경우엔 Strapi 미디어가 그렇게 크지는 않아서 nginx 단만 100m 으로 풀어 두었다. 첨부 파일 평균이 수십 MB 를 넘기 시작 하면 그땐 직업 업로드 경로로 갈아 탈 예정이다.