-
Django서버에 간단한 HTTPS Let's Encrypt 적용하기Django 2022. 7. 30. 21:46
서론
웹 서비스에 기본적으로 들어가는 https는 nginx 설정, ssl 발급, 키파일 적용까지
필자에게는 너무 복잡하고 어려운 일이었다.그러나 아래 레퍼런스의 튜토리얼을 보고 간단하게 ssl 적용하는 내용을 기억할 겸 다시 적어보는 내용이다.
그리고 튜토리얼 답게 정말 간단하게 사용이 가능하다.
글로만 설명 해보면
1. docker-compose로 nginx-proxy, acme-companion(let's encrypt) 연결
2. 환경변수를 통한 도메인 ssl 적용
그리고 인증서의 만료는 3개월이나
자동으로 인증서를 체킹 하여, 갱신해준다 (필자가 직접 3개월 동안 뒀더니 자동으로 갱신되었다.)
주의사항
- docker container를 사용하여 무료 ssl인 let's encrypt를 적용하는 내용입니다.
- 레퍼런스 그대로 따라가면서 최신 docker image를 사용한 내용이라 레퍼런스와 조금 다를 수 있습니다
본론
해야 할 내용
1. docker-compose로 nginx-proxy와 acme-companion(let's encrypt) 연결
nginx-proxy와 acme-companion(let's encrypt)를 볼륨으로 연결
2. 도메인 준비
당연하지만 ssl을 적용하려면 도메인이 필요하다.
도메인은 환경변수에 적용하면 됩니다.3. 환경변수
let's encrypt에 적용될 도메인 host와
nginx에 적용될 port 정보가 필요하므로 env 파일을 만들어 적용한다.
이하 파일의 환경변수는 필자의 프로젝트에 썼던 파일들입니다.
docker-compose.prod.yml
certs, vhost, html, docker.sock을 volume으로 nginx와 let's encrypt 연결
version: '3.8' services: ########################### web: container_name: web build: context: ./company_review dockerfile: Dockerfile/Dockerfile.prod command: gunicorn config.wsgi:application --bind 0.0.0.0:8000 ports: - 8000 env_file: - ./.env/.env.prod volumes: - static:/usr/src/company_review/static - media:/usr/src/company_review/media ########################### redis: image: redis:6.2.6-alpine ports: - 6379:6379 volumes: - redis_data:/etc/redis_data/data depends_on: - web ########################### nginx-proxy: container_name: nginx-proxy restart: always build: context: nginx ports: - 80:80 - 443:443 volumes: - certs:/etc/nginx/certs - vhost:/etc/nginx/vhost.d - html:/usr/share/nginx/html - /var/run/docker.sock:/tmp/docker.sock:ro - static:/usr/src/company_review/static - media:/usr/src/company_review/media depends_on: - web ########################### nginx-proxy-acme: container_name: nginx-proxy-acme image: nginxproxy/acme-companion volumes: - certs:/etc/nginx/certs - vhost:/etc/nginx/vhost.d - html:/usr/share/nginx/html - /var/run/docker.sock:/var/run/docker.sock:ro - acme:/etc/acme.sh env_file: - ./.env/.env.prod.nginx_acme depends_on: - nginx-proxy ########################### volumes: redis_data: certs: vhost: html: acme: static: media:
.env.prod
VIRTUAL_HOST와 VIRTUAL_PORT로 nginx에 적용할 호스트를 적고,
LETSENCRYPT_HOST로 let's encrypt에 적용할 도메인을 정의해준다.
다른 env는 django에 사용되는 env이므로 설정하지 않아도 된다.
DEBUG=False STAGE=PROD DJANGO_SETTINGS_MODULE=config.settings.prod VIRTUAL_HOST=mixedprogramming.net VIRTUAL_PORT=8000 LETSENCRYPT_HOST=mixedprogramming.net
.env.prod.nginx_acme
nginx-proxy와 acme-companion(let's encrypt) 연결을 위한 컨테이너 명 지정
email은 ssl 적용 후 만료 알람 등 이메일 보내는 용도
DEFAULT_EMAIL=skarndrkd1@naver.com NGINX_PROXY_CONTAINER=nginx-proxy
let's encrypt 인증에는 시간당 횟수 제한이 있으므로 테스트 환경에서는 아래의 staging letsencrypt를 추가하여 사용하도록 하자
ACME_CA_URI=https://acme-staging-v02.api.letsencrypt.org/directory
이후 적용된 nginx / default.conf
아래 코드를 보면 단순 env 설정만으로 도메인, 포트 연결이 된 걸 알 수 있다.
당연하겠지만 ssl도 적용이 완료되었다.
#default.conf
... # 생략 # mixedprogramming.net upstream mixedprogramming.net { ## Can be connected with "job-search-and-company-review_default" network # web server 172.18.0.3:8000; } server { server_name mixedprogramming.net; listen 80 ; access_log /var/log/nginx/access.log vhost; # Do not HTTPS redirect Let'sEncrypt ACME challenge location ^~ /.well-known/acme-challenge/ { auth_basic off; auth_request off; allow all; root /usr/share/nginx/html; try_files $uri =404; break; } location / { return 301 https://$host$request_uri; } } server { server_name mixedprogramming.net; listen 443 ssl http2 ; access_log /var/log/nginx/access.log vhost; ssl_session_timeout 5m; ssl_session_cache shared:SSL:50m; ssl_session_tickets off; ssl_certificate /etc/nginx/certs/mixedprogramming.net.crt; ssl_certificate_key /etc/nginx/certs/mixedprogramming.net.key; ssl_dhparam /etc/nginx/certs/mixedprogramming.net.dhparam.pem; ssl_stapling on; ssl_stapling_verify on; ssl_trusted_certificate /etc/nginx/certs/mixedprogramming.net.chain.pem; add_header Strict-Transport-Security "max-age=31536000" always; include /etc/nginx/vhost.d/default; location / { proxy_pass http://mixedprogramming.net; } }
Reference
Django on Docker Series:
Dockerizing Django with Postgres, Gunicorn, and Nginx
Securing a Containerized Django Application with Let's Encrypt
Deploying Django to AWS with Docker and Let's Encrypt
'Django' 카테고리의 다른 글
django-jsonform을 사용한 django admin 활용 (0) 2024.07.21 drf_spectacular를 사용한 api docs 만들기 (0) 2022.11.20 django.core.exceptions.SuspiciousFileOperation: Detected path traversal attempt (0) 2021.08.02 Django queryset distinct and sort (0) 2021.08.02 Django to AWS S3 업로드간 발생하는 I/O operation on closed file 해결방법 (0) 2021.06.21