https://pentacent.medium.com/nginx-and-lets-encrypt-with-docker-in-less-than-5-minutes-b4b8a60d3a71
Nginx and Let’s Encrypt with Docker in Less Than 5 Minutes
Getting Nginx to run with Let’s Encrypt in a docker-compose environment is more tricky than you’d think …
pentacent.medium.com
여기에서 시키는 대로만 하면 빠르게 https 설정 할 수 있습니다. 글 제목에는 5분 걸린다고 써있는데 저는 영어를 잘 못해서 50분 걸렸네요. 아래에 나름대로 내용 요약 + 쓸데없는 첨언을 해봤습니다.
도커 깔려있는 EC2 환경 기준 설정 방식에 대해 설명합니다. 순서는 다음과 같습니다.
1. 작업할 위치에서 설정 파일 docker-compose.yml 을 작성합니다.
services:
nginx:
image: nginx:1.15-alpine
ports:
- "80:80"
- "443:443"
volumes:
- ./data/nginx:/etc/nginx/conf.d
- ./data/certbot/conf:/etc/letsencrypt
- ./data/certbot/www:/var/www/certbot
# command: "/bin/sh -c 'while :; do sleep 6h & wait $${!}; nginx -s reload; done & nginx -g \"daemon off;\"'"
certbot:
image: certbot/certbot
volumes:
- ./data/certbot/conf:/etc/letsencrypt
- ./data/certbot/www:/var/www/certbot
# entrypoint: "/bin/sh -c 'trap exit TERM; while :; do certbot renew; sleep 12h & wait $${!}; done;'"
nginx는 서버에 들어오는 http 요청을 받아서 SSL 인증을 적용하고 그 요청을 https 요청으로 redirect 해줄겁니다. 포트 정보에 80번 http 포트와 443번 https 포트가 기입된 걸 볼 수 있네요.
certbot은 nginx의 보안 설정(SSL)을 위한 인증서를 발급받는 프로그램입니다. 원래는 돈 주고 받아야 되는데.. certbot을 사용하면 기간제지만 무료로 받을 수 있습니다.
2. 같은 위치를 기준으로 하위에 data/nginx 폴더를 만들고 그 안에 app.conf 파일을 아래와 같이 작성합니다.
server {
listen 80;
server_name 내 도메인 주소;
location / {
return 301 https://$host$request_uri;
}
location /.well-known/acme-challenge/ {
root /var/www/certbot;
}
}
server {
listen 443 ssl;
server_name 내 도메인 주소;
location / {
# 프론트 서버 경로
proxy_pass http://내 도메인 주소:3000;
}
location /api {
# 백 서버 경로
proxy_pass http://내 도메인 주소:8080;
}
ssl_certificate /etc/letsencrypt/live/내 도메인 주소/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/내 도메인 주소/privkey.pem;
include /etc/letsencrypt/options-ssl-nginx.conf;
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
}
도메인 주소만 채워 넣어주고 location 블록만 커스텀하시면 됩니다. 나머지는 기본 틀이나 보안 인증 관련 부분이예요.
https로 변환되어 443번 포트로 서버에 들어온 요청은 nginx가 잡아서, uri가 가장 일치하는 location 블록으로 매핑해줍니다.
uri는 요청에서 도메인 주소 뒤에 붙는 내용이라고 생각하면 편합니다. 제 도메인 주소가 taegun1011.com이라면 https://taegun1011.com/home이라는 요청에서 /home이 uri겠죠.
백/프론트 서버를 가지고 단순하게 구동하려면 위처럼 /api로 시작하는 uri는 백엔드 서버의 포트로, 나머지 uri는 프론트 서버의 포트로 연결해주면 될 듯 합니다. 추가 설정까지는 바라지 말아주세요. 뇌피셜이지만 여러 서비스의 백엔드 엔드포인트가 /api로 시작하는 이유가 nginx 설정과 관련있을 듯 하네요.
3. 임시 인증서 받아오기
그런데 문제가 있습니다. certbot은 nginx가 작동되어야 인증서를 받아올 수 있고, nginx는 인증서가 있어야 작동할 수 있습니다. 데드락에 빠졌네요. 다행히 위 사이트에서는 임시 인증서를 받을 수 있는 방법을 제공합니다. 아래 명령어를 통해 더미 인증서 발급을 위한 쉘 스크립트를 다운받읍시다.
curl -L https://raw.githubusercontent.com/wmnnd/nginx-certbot/master/init-letsencrypt.sh > init-letsencrypt.sh
이 파일을 바로 사용할 수는 없고, vi 에디터로 내용을 조금 수정해야 합니다.
- 8행의 domains에 서버 도메인을 적어주세요. www로 시작하는 건 없어도 됩니다.
- 11행의 email에 본인 이메일을 적어주세요. 사용할 일은 없는데 입력하지 않으면 인증서 발급이 안됩니다.
- 이 쉘 스크립트는 docker-compose를 사용합니다. 그런데 "docker-compose"와 "docker compose"는 달라요. docker만 깔려있으면 "docker compose"는 실행할 수 있지만 구 버전인 "docker-compose"는 실행할 수 없습니다. 굳이 구 버전을 설치하지 말고 스크립트의 docker-compose를 docker compose로 바꿔줍시다.
일일히 바꿔도 되지만... :%s/docker-compose/docker compose 를 입력하면 파일 전체에서 찾아 바꾸기를 수행해줘서 편합니다. 다만 3행의 docker compose는 docker로 바꿔주세요. 해당 조건문은 'docker'의 버전을 확인해서 도커가 깔려있는 지 확인하는 겁니다. docker compose는 명령어의 일부니까 버전이 없죠.
4. (필요할 경우) 인증서 주기적으로 갱신 설정
저는 서버를 그리 오래 사용하지는 않을 예정이라 인증서를 갱신할 필요가 없습니다. 그래서 해당 부분을 혹시 몰라 주석 처리 해놨어요. 인증서를 주기적(6시간, 12시간마다)으로 갱신하시려면 들여쓰기에 유의해서 주석을 풀어두시면 됩니다.
5. 인증서 받고 실행
chmod +x init-letsencrypt.sh
sudo ./init-letsencrypt.sh
로 쉘을 실행하고 인증서를 받아주세요. 파일을 제대로 수정하셨다면 오류가 발생할 일은 없을 겁니다!! 만약 오류가 발생해도, 될 때까지 하겠다고 스크립트를 반복해서 실행하지 마세요. 인증을 너무 자주 시도하면 1시간 정도 certbot 서버에 접속이 차단됩니다. 어떻게 아는 지는 묻지 마세요.
인증서 설치가 됐으면 docker compose up -d 로 nginx 컨테이너를 구동하시면 됩니다.
따라하다 문제가 생기면 알려주시면 감사하겠습니다.