ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 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

     

    Dockerizing Django with Postgres, Gunicorn, and Nginx

    This tutorial details how to configure Django to run on Docker along with Postgres, Nginx, and Gunicorn.

    testdriven.io

    Securing a Containerized Django Application with Let's Encrypt

     

    Securing a Containerized Django Application with Let's Encrypt

    In this tutorial, we'll look at how to secure a containerized Django app running behind an HTTPS Nginx proxy with Let's Encrypt SSL certificates.

    testdriven.io

    Deploying Django to AWS with Docker and Let's Encrypt

     

    Deploying Django to AWS with Docker and Let's Encrypt

    In this tutorial, we'll deploy a Django app to AWS EC2 with Docker and Let's Encrypt.

    testdriven.io

     

     

     
     
     
     

    댓글

Designed by Tistory.