EB로 배포한 프로젝트에 이미지 파일을 업로드 할 때 아래와 같은 에러가 뜨는 경우가 있었다.
내가 이미지 업로드 했을 때는 분명 정상적으로 되는데 다른 분이 업로드 했을 때는 정상적으로 되지 않았다.
그래서 컴퓨터 환경마다 다른가? 생각했는데 혹시나 해서 용량이 큰 이미지를 업로드 해봤다. 업로드가 안 된다... 다른 분이 용량이 큰 이미지를 업로드 하려고 하셨나 보다.
아래와 같은 에러가 웹 브라우저 콘솔에 떴다.
POST https://api.~~~net::ERR_FAILED 413
Access to XMLHttpRequest at 'https://api.~~~' from origin 'https://www.~~~' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
HTTP 413 상태 코드(Payload Too Large)는 요청 엔티티가 서버에 의해 정의된 제한보다 크다는 것을 나타낸다.
CORS 에러가 뜨는 것은 응답 헤더에 Access-Control-Allow-Origin 부분이 없기 때문에 요청을 보내는 클라이언트에게 이를 볼 수 있는 권한이 없다는 것이다. ??? 난 분명 스프링 시큐리티에서 CORS 설정을 했는데 왜 CORS 에러가 뜨지??
Nginx사용 시4xx또는5xx오류에 대해 서버는Access-Control-Allow-Origin를 응답 헤더에 추가하지 않는다. 서버는2xx과3xx(redirection)에 대해서만 해당 헤더를 보낸다.
만약4xx또는5xx오류에 대해서도Access-Control-Allow-Origin를 응답 헤더에 추가하고 싶다면Nginx에서 아래와 같이 추가하면 된다.add_header <header_name> <value> always# 예시 add_header 'Access-Control-Allow-Origin' '*' always
참고
https://stackoverflow.com/questions/60537280/why-browsers-display-cors-error-in-case-of-response-413
따로 설정한 거 아니면 4xx, 5xx 에러에 대한 CORS 에러는 뜨는 거니까, 그럼 413 에러를 해결하면 자동으로 CORS 문제가 해결이 된다는 말씀!! 413 에러를 해결해보자.
CORS 설정을 했는데도 CORS 문제가 413 에러 뿐만 아니라 4xx, 5xx 에러와 같이 발생한다면 당황하지 말 것!왜 1MB로 제한을 했을까??
EB를 이용해서 웹 서비스를 Deploy 할 경우 어플리케이션의 Reverse Proxy로 사용되는 Nginx의 설정 때문이다. Nginx의 설정 값 중 client_max_body_size를 이용하면 client가 너무 큰 사이즈의 request를 보내지 못 하도록 제한을 걸 수 있다. 이 설정은 request의 Content-Length 헤더값이 client_max_body_size에 설정된 값을 넘을 수 없도록 제한한다.
악의적인 대용량 파일 업로드 등을 방지하는데 사용한다.
그럼 어떻게 Nginx의 업로드 크기 제한을 수정할 수 있을까?
파일 업로드 사이즈를 설정하기 위해서는 먼저 nginx의 설정파일을 수정해야 한다. nginx.conf 파일은 아래의 경로에 있다. 읽기 전용이므로 root 계정이 필요하다.
$ vim /etc/nginx/nginx.conf
설정된 부분으로 이동한 후 http { } 안에 해당 속성과 값을 추가하거나 변경해야 한다. 이때 client_max_body_size 속성과 값을 설정해야 한다. 만약 50MB까지 허용하는 경우라면 아래처럼 설정한다.
http {
client_max_body_size 50M;
...
}
업로드 크기에 대해 수정이 되었으면
# nginx 재시작
nginx -s reload
또는
# service 재시작
service nginx restart
하면 된다.
위에서 설명한 부분은 Nginx에 대해 직접 설정할 때 사용하면 될 것 같은데, 내가 적용하려고 하는 건 AWS EB에 Docker 환경으로 배포되고 있는 프로젝트다.
EB를 통해 생성된 EC2에 SSH로 접속해서 Nginx에 대한 파일을 찾아 위 방법대로 설정하면 할 수는 있겠지만 만약에 AutoScaling으로 EC2가 추가로 생성된다면 또 해당 EC2에 접속해 또 설정해야 할 것이다.
나는 GitHub Actions와 EB로 무중단 배포를 하고 있는데... 어떻게 해야 하지??
Amazon Linux2 이전에는
|-- .ebextensions
| `-- nginx
| `-- conf.d
| `-- myconf.conf
`-- 프로젝트 파일들
위 구조로 .conf 파일에 Nginx 관련 설정을 추가하면 된다고 한다.
하지만 내가 적용하는 프로젝트는 Amazon Linux2다. .ebextensions 대신 .platform을 사용한다고 한다.
|-- .platform
| `-- nginx
| `-- conf.d
| `-- myconf.conf
`-- 프로젝트 파일들
.conf 파일의 내용은 아래와 같다.
# nginx의 기본 업로드 제한 1MB
# 제한 풀기 -> 0
client_max_body_size 0;
0을 넣으면 제한을 풀 수 있고 원하는 크기(예를 들면 50MB -> 50M)를 지정할 수도 있다.
어떤 답변을 보면
|-- .platform
| `-- nginx
| `-- conf.d
| `-- myconf.conf
| `-- 00_myconf.config
`-- 프로젝트 파일들
00_myconf.config 파일이 .platform 바로 아래 위치에 넣는 게 추가 되었는데
이 파일의 내용은 아래와 같다.
container_commands:
01_reload_nginx:
command: "service nginx reload"
Nginx 서비스를 다시 재시작하는 것이다.
근데 EB에 deploy 할 때 Nginx를 다시 시작하기 때문에 .config 파일은 필요 없을 것 같다고 한다.
|-- .platform
| `-- nginx
| `-- conf.d
| `-- myconf.conf
`-- 프로젝트 파일들
이 방법으로 하고 GitHub Actions를 돌려서 초록불이 들어왔다! 설렘 반 기대 반
구축한 웹 사이트에 들어가 1MB가 넘는 이미지를 업로드 했더니!! 뭐야 똑같네 안 되네...
허무했지만 하나의 댓글이 눈에 띄었다.

맞아 나 도커 환경 EB였지... 그럼 Dockerrun.aws.json 파일과 관련이 있을 거야...
GitHub Actions로 배포하기 전에 테스트로 EB Console로 직접 업로드 해봐야지..!

클릭!

파일 선택을 누르기 앞서
Dockerrun.aws.json 파일과 .platform/nginx/conf.d/myconf.conf 파일을 zip으로 압축한다.
압축한 zip 파일을 위 사진의 파일 선택 버튼을 통해 선택한다!
그리고 배포를 똿! 누르면
고래 왼쪽으로 상태가 빙글빙글 돈다. 과연... 될까???

✅ 초록!
그럼 이제 웹 사이트로 가서 업로드가 잘 되는지 보자

너무 잘 올라가고,,,
감사합니다... 구박사님, 스택 오버플로우 박사님들,,,
그럼 이제 진짜 진짜 마지막으로 GitHub Actions에서 배포했을 때 자동으로 적용되게 수정을 해야겠지!
.github/workflows/deploy.yml로 가보자
- name: Generate deployment package
run: |
mkdir -p deploy
cp Dockerrun.aws.json deploy/Dockerrun.aws.json
cd deploy && zip -r deploy.zip .
이 부분만 손 보면 된다.
기존에는 deploy 디렉토리를 만들어 Dockerrun.aws.json 파일을 deploy 디렉토리 안으로 복사하고 해당 디렉토리로 들어가 zip으로 압축했다.
근데 이제는 .platform/nginx/conf.d/myconf.conf 파일도 같이 압축해야 하기 때문에
- name: Generate deployment package
run: |
mkdir -p deploy/.platform/nginx/conf.d
cp Dockerrun.aws.json deploy/Dockerrun.aws.json
cp .platform/nginx/conf.d/myconf.conf deploy/.platform/nginx/conf.d/myconf.conf
cd deploy && zip -r deploy.zip .
위와 같이 수정했다.
수정하고 deploy 브랜치에 push 하니까 GitHub Actions가 노란색으로 빙빙 돈다.

✅ 초록불이다 ㅎㅎ
웹 사이트로 들어가서 이미지를 업로드 해보니 아주 잘 올라간다!
하지만 파일의 용량이 크다 보니 속도가 느려진 느낌이 든다.
이 부분에 대해서는 부하 테스트를 진행해보고 개선해보는 방향으로 나아가야 할 것 같다.
오늘의 삽질 끝!
넘넘 유익해요!