docker compose + certbot

이민기·2022년 8월 14일
0
post-thumbnail

Docker 란 무엇인가???

Docker는 반복적이고 일상적인 구성 작업을 없애고 데스크톱 및 클라우드와 같은 빠르고 쉽고 이식 가능한 애플리케이션 개발을 위해 개발 수명 주기 전반에 걸쳐 사용됩니다. Docker의 포괄적인 종단 간 플랫폼에는 전체 애플리케이션 제공 수명 주기에서 함께 작동하도록 설계된 UI, CLI, API 및 보안이 포함됩니다.
쉽게 말해.. 배포 자동화 구현을 해주고 컨테이너를 만들어 깔끔한 상태로 버전관리를 쉽게 할수 있다.

그럼 Docker 파일은 어떻게 작성해???

리눅스에서 docker-compose를 설치하는것 부터 해보도록 하겠다.

sudo apt update
sudo apt-get update
sudo apt install docker-compose

일단 ubuntu 환경 기준으로 설명을 드리자면, ubuntu를 일단 업그레이드 해주고..

docker-compose 를 설치해 주자..

설치가 끝났다면, docker-compose 를 이용하여, 컨테이너를 만들고 컨테이너를 백그라운드로 실행시킬수 있다.

Django docker 및 docker-compose 파일 예시

Dockerfile

FROM python:3.8.13

ENV PYTHONBUFFERED=1
ENV PYTHONDONTWRITEBYTECODE=1

RUN apt-get -y update
RUN apt-get install -y locales

RUN mkdir /srv/docker-server
ADD . /srv/docker-server

WORKDIR /srv/docker-server

RUN pip install --upgrade pip
RUN pip install -r requirements.txt

EXPOSE 8000

Dockerfile 예시 이다. 파일명은 Dockerfile로 만들어 주었다.

버전은 파이썬 3.8.13 인데. 도커에서 지원되는 버전으로 입력해 주어야 한다.

기본적인 리눅스 업데이트 및 워킹 디렉토리도 지정해 주었다.

백엔드 서버를 8000으로 열어야 하기에 expose 8000을 입력해 주었다..

8000번을 쓰겠다는 얘기다..

docker-compose.yml

version: '3.8'

services:
  backend:
    build: .
    command: gunicorn --bind 0.0.0.0:8000 config.wsgi:application
    volumes:
      - ./:/srv/docker-server/
    env_file:
      - ./.env
    ports:
     - 8000:8000
    working_dir: /srv/docker-server/
    restart: always

  nginx:
    image: nginx
    volumes:
      - ./nginx/default.conf:/etc/nginx/conf.d/default.conf
      - ./static/:/static/
      - ./data/certbot/conf:/etc/letsencrypt
      - ./data/certbot/www:/var/www/certbot
    ports:
      - "80:80"
      - "443:443"
    depends_on :
      - backend
    restart: always

  certbot:
    image: certbot/certbot
    volumes:
      - ./data/certbot/conf:/etc/letsencrypt
      - ./data/certbot/www:/var/www/certbot

일단 크게 backend 컨테이너 nginx 컨테이너 certbot 컨테이너를 만들었다.

certbot은 https 인증서를 위해서 설치를 해주어야 한다.

certbot을 사용하기 위하여, init-letsencrypt.sh 파일을 이용하여, 키를 복사해 오자.

dokcer-compose 에 원하는 컨테이너는 필요할때 생성해 줄수 있다.

nginx에서는 80번 포트와 443 포트 지정해 주었다.

init-letsencrypt.sh

#!/bin/bash

if ! [ -x "$(command -v docker-compose)" ]; then
  echo 'Error: docker-compose is not installed.' >&2
  exit 1
fi

domains=(example.org www.example.org)
rsa_key_size=4096
data_path="./data/certbot"
email="" # Adding a valid address is strongly recommended
staging=0 # Set to 1 if you're testing your setup to avoid hitting request limits

if [ -d "$data_path" ]; then
  read -p "Existing data found for $domains. Continue and replace existing certificate? (y/N) " decision
  if [ "$decision" != "Y" ] && [ "$decision" != "y" ]; then
    exit
  fi
fi


if [ ! -e "$data_path/conf/options-ssl-nginx.conf" ] || [ ! -e "$data_path/conf/ssl-dhparams.pem" ]; then
  echo "### Downloading recommended TLS parameters ..."
  mkdir -p "$data_path/conf"
  curl -s https://raw.githubusercontent.com/certbot/certbot/master/certbot-nginx/certbot_nginx/_internal/tls_configs/options-ssl-nginx.conf > "$data_path/conf/options-ssl-nginx.conf"
  curl -s https://raw.githubusercontent.com/certbot/certbot/master/certbot/certbot/ssl-dhparams.pem > "$data_path/conf/ssl-dhparams.pem"
  echo
fi

echo "### Creating dummy certificate for $domains ..."
path="/etc/letsencrypt/live/$domains"
mkdir -p "$data_path/conf/live/$domains"
docker-compose run --rm --entrypoint "\
  openssl req -x509 -nodes -newkey rsa:$rsa_key_size -days 1\
    -keyout '$path/privkey.pem' \
    -out '$path/fullchain.pem' \
    -subj '/CN=localhost'" certbot
echo


echo "### Starting nginx ..."
docker-compose up --force-recreate -d nginx
echo

echo "### Deleting dummy certificate for $domains ..."
docker-compose run --rm --entrypoint "\
  rm -Rf /etc/letsencrypt/live/$domains && \
  rm -Rf /etc/letsencrypt/archive/$domains && \
  rm -Rf /etc/letsencrypt/renewal/$domains.conf" certbot
echo


echo "### Requesting Let's Encrypt certificate for $domains ..."
#Join $domains to -d args
domain_args=""
for domain in "${domains[@]}"; do
  domain_args="$domain_args -d $domain"
done

# Select appropriate email arg
case "$email" in
  "") email_arg="--register-unsafely-without-email" ;;
  *) email_arg="--email $email" ;;
esac

# Enable staging mode if needed
if [ $staging != "0" ]; then staging_arg="--staging"; fi

docker-compose run --rm --entrypoint "\
  certbot certonly --webroot -w /var/www/certbot \
    $staging_arg \
    $email_arg \
    $domain_args \
    --rsa-key-size $rsa_key_size \
    --agree-tos \
    --force-renewal" certbot
echo

echo "### Reloading nginx ..."
docker-compose exec nginx nginx -s reload

상단에 도메인과 이메일은 자신에 맞는 도메인과 이메일로 수정해 주어야 한다.

상단 파일은 curl 을 통해서 해당 url에서 받아오자.

curl -L https://raw.githubusercontent.com/wmnnd/nginx-certbot/master/init-letsencrypt.sh > init-letsencrypt.sh

sudo chmod +x init-letsencrypt.sh

상단 명령어로 권한을 주고 실행 해 보자..

sudo ./init-letsencrypt.sh

인증서가 없다면, 아마존 Certificate Manager 를 통해서 무료로 발급 받을수 있다.

route 53에 cname을 등록해 주어야 하는데 그것까진 무료인지는 모르겠다.

0.5달러 나갔던거 같음.....ㅠ

저는 aws를 사용하지 않고 국내 linux 서버를 이용하였는데...아주 잘되었다...

여튼 이렇게 끝나고 나면...끝..

docker-compose 기본 명령어

docker-compose build #컨테이너를 만든다
docker-compose up #컨테이너를 실행한다.
docker-compose up -d #컨테이너를 백그라운드로 실행한다.
docker-compose down #컨테이너를 내린다.
docker-compose kill #컨테이너가 잘 안꺼지면, 죽인다??????ㅋ

다들 부디 성공하시길.......

아 ...nginx에 들어가는 conf 파일도 공유하도록 하겠습니다.

upstream dj_backend {
    server backend:8000;
}

server {
    listen       80;
    server_name  example.com www.example.com; # www 있으면 추가
    client_max_body_size 100M;

    location / {
        return 301 https://$host$request_uri;
    }

    location /.well-known/acme-challenge/ {
        root /var/www/certbot;
    }
}

server {
    listen 443 ssl;
    server_name example.com www.example.com; # www 있으면 추가
    client_max_body_size 100M;

    location / {
        proxy_pass http://dj_backend;
        proxy_set_header X-Forwarded-for $proxy_add_x_forwarded_for;
        proxy_set_header Host $host;
        proxy_redirect off;
    }

    location /static/ {
        alias /static/;
    }

    location /media/ {
        alias /media/;
    }

    ssl_certificate /etc/letsencrypt/live/dk-backend.shop/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/dk-backend.shop/privkey.pem;
    include /etc/letsencrypt/options-ssl-nginx.conf;
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
}

tip 장고 기본 static 파일은 collect

python manage.py collectstatic

해주셔요~

profile
지나가는사람

0개의 댓글