패션-클라우드 배포 히스토리

기존에 작업하던 사이드 프로젝트 POC 발표 기간이 별로 남지 않았고, AWS 비용 지원도 나와서 CloudType, Neon 조합으로 무료 플랜을 활용해서 배포해두었던 백엔드 인프라를 AWS 기반으로 마이그레이션하고, 프론트 신규 배포를 진행하였다. 배포하면서 여러 이슈 상황이 있었는데 해당 히스토리를 정리해두었다.

AWS 서비스의 경우, 기존에 static 파일 저장 스토리지 용도로 사용하던 S3를 유지한 채, EC2를 추가적으로 사용하였다. EC2 인스턴스 유형의 경우, 유효한 트래픽이 없는 상태에서 RDS 서비스를 사용하기에는 비용적으로 팀원들에게 부담이 되므로 DB를 인스턴스 내부에 docker 컨테이너로 띄울 계획으로 vCPU가 2개에 메모리가 2Gib인 t3.small를 사용하였다.

DNS의 경우, CloudFlare에서 도메인을 사두었고, SSL/TLS 설정시 편의성을 위해 CloudFlare를 사용하였다. 

 

1. NGINX 도커 컨테이너 conf 적용 이슈

SpringBoot 기반 백엔드, Redis, DB, NGINX 총 3개의 서비스를 docker-compose를 사용해서 관리하려했는데 NGINX 컨테이너에서 아래와 같은 에러코드가 발생하면서 exitCode 1과 함께 컨테이너가 내려가는 이슈가 발생하였다.

/docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration
/docker-entrypoint.sh: Looking for shell in /docker-entrypoint.d/


해당 원인은 nginx 도커파일과 사용하려던 nginx.conf 파일의 설정이 잘못되어 있어서 nginx가 실행되지 않고, 에러를 발생시켜 생기는 이슈였다. 해당 이슈로 NGINX 이미지를 docker-compose.yml에서 제거한 후, 인스턴스 내부에 직접 NGINX를 설치하여 /etc/nginx/conf.d 폴더 내부에 prod.conf로 웹서버 설정을 직접 잡아주는 방식으로 처리하였다.

 

2. Vercel 배포시 DNS "err_too_many_redirects" 이슈

프론트엔드의 경우, NextJs 기반으로 작동하므로 NextJs 프레임워크를 만든 Vercel에 배포하는 것이 안정성 측면이나 CI/CD 설정 측면에서도 편의성을 가져갈 수 있다고 판단하였다. Vercel과 Github 프론트엔드 레포를 연동하고, build해서 vercel 자체적인 도메인으로 정상적으로 접근가능한 것까지 확인 후, 구매하였던 도메인과 연동하였는데 해당 도메인으로 접근시 "err_too_many_redirects" 페이지가 뜨면서 페이지로 접근이 불가하였다. 

해당 이슈의 원인은 CloudFlare SSL/TLS 설정 문제였다. CloudFlare의 SSL/TLS 설정을 가변 옵션으로 설정해두고 쓰고 있었는데 가변 옵션 사용시, CloudFlare가 HTTP로 Vercel 배포 주소에 접근 후, Vercel의 응답에 따라 HTTPS를 사용해서 응답을 포워딩해주는 방식이었다. 여기서 문제는 Vercel이 CloudFlare로 응답할 때, 자동으로 HTTP 요청을 HTTPS로 업그레이드하여 308 코드를 전송하므로 동일한 위치로 리다이렉트 되어 루프에 빠지게된다. CloudFlare의 SSL/TLS 옵션을 "전체(엄격)" 옵션으로 변경하여 해당 이슈를 처리하였다.

 

3. 웹서버 DNS 접속 불가 "Error 521: Web server is down" 이슈

Vercel과 CloudFlare 연동이 완료된 이후, api 서버에 연동해두었던 도메인으로 접근시,  CloudFlare의 521 에러 페이지가 뜨는 이슈가 있었다. api 서버에 에러가 발생하여 NGINX 서비스가 down된 것으로 추정하여 ssh로 EC2 인스턴스에 접근하여 상태 확인 결과 docker 컨테이너와 NGINX 서비스 모두 정상적으로 동작하고 있었다.

해당 이슈의 원인은 Vercel과 CloudFlare 연동 이슈를 처리하면서 CloudFlare SSL/TLS 옵션을 "전체(엄격)" 옵션으로 변경한 것이었다. SSL/TLS 옵션을 "전체(엄격)"으로 사용하면, 엔드투엔드로 브라우저 - CloudFlare - 서버 전체 트래픽단을 암호화하기위해 CloudFlare가 제공하는 CA 인증서가 웹서버에 등록되어 있어야했다. 

EC2 인스턴스에 /etc/ssl 디렉토리에 CloudFlare에서 제공하는 ssl 인증 pem 파일과 key 파일을 추가해두고, NGINX의 prod.conf 설정파일에 443 포트를 열어두고 ssl 관련 설정을 적용하여 해당 이슈를 처리하였다.

server {
    listen   443;

    ssl    on;
    ssl_certificate    /etc/ssl/your_domain_name.pem;
    ssl_certificate_key    /etc/ssl/your_domain_name.key;
}