Docker Compose 환경에서 Certbot으로 Nginx SSL 설정하기

Nginx 컨테이너와 Certbot 컨테이너 간 볼륨 공유

Cerbot은 SSL 발급 및 갱신을 위해 일정한 위치에 파일을 생성하거나 HTTP 응답을 제공할 수도 있습니다. 이때 Nginx 컨테이너와 Certbot 컨테이너 간 볼륨 공유가 필수적입니다.

기본적인 Docker Compose 설정

services:
  nginx:
    image: nginx:mainline-alpine
    container_name: nginx
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./nginx/default.conf:/etc/nginx/conf.d/default.conf
      - ./htdocs:/usr/share/nginx/html
      - ./letsencrypt:/etc/letsencrypt
    networks:
      - web
networks:
  web:

위 예시에서는 다음 세 가지가 핵심입니다.

  • 7번째 줄, SSL이 설정된 경우 사용할 443 포트
  • 10번째 줄, HTTP Challenge 사용에 필요한 htdocs 디렉토리
  • 11번째 줄, 인증서 저장에 필요한 letsencrypt 디렉토리

Certbot 컨테이너가 위 볼륨들과 동일한 디렉토리를 공유해야 challenge와 인증서 파일이 Nginx에서도 인식될 수 있습니다.

Certbot을 처음 사용하는 경우, letsencrypt 디렉토리가 존재하지 않는다면 직접 생성해 주어야 합니다.

mkdir -p letsencrypt

Nginx에서 설정한 도메인의 root 경로 확인

Nginx 설정에서 도메인의 root 경로를 볼륨과 동일하지 않게 설정하는 경우도 있습니다.

server {
  listen 80;
  server_name example.com;

  root /usr/share/nginx/html/example.com;
  index index.html index.htm;

  location / {
    try_files $uri $uri/ =404;
  }

  location ~ /\.ht {
    deny all;
  }
}

이 경우 Certbot은 htdocs 디렉토리가 아닌 htdocs/example.com 디렉토리를 볼륨으로 사용해야 인증이 가능합니다.

Certbot 사용하기

Nginx가 실행 중인 상태에서 Certbot을 사용하는 경우 특별한 이슈가 없다면 일반적으로 webroot 인증 방식을 사용합니다.

docker run --rm \
  -v ./letsencrypt:/etc/letsencrypt \
  -v ./htdocs:/var/www/html \
  certbot/certbot certonly \
  --webroot -w /var/www/html \
  -d example.com

Certbot에서 사용할 볼륨의 상대 경로는 compose.yaml의 letsencrypt 디렉토리 경로 및 Nginx에서 사용 중인 root 디렉토리의 경로와 동일해야 합니다.

Certbot 컨테이너의 볼륨이 지정하는 root 경로는 Nginx 설정과 관련이 없으며 Certbot 컨테이너 내부에서만 사용됩니다.

Certbot의 각 인증 방식과 차이점

Certbot은 세 가지 주요 인증 방식을 지원합니다.

HTTP 방식

  • 웹 서버가 실행 중일 때 사용할 수 있습니다.
  • .well-known/acme-challenge 경로를 통해 인증 요청을 수행합니다.
  • 인증을 위해 웹 루트를 공유해야 합니다.
docker run --rm -v ./letsencrypt:/etc/letsencrypt \
certbot/certbot certonly --webroot -d example.com

Standalone 방식

  • 자체 웹서버를 실행하여 인증 요청을 수행합니다.
  • 80/443 포트를 사용하는 웹 서버를 일시적으로 중단해야 합니다.
docker compose stop nginx
docker run --rm -v ./letsencrypt:/etc/letsencrypt \
certbot/certbot certonly --standalone -d example.com
docker compose start nginx

DNS 방식

  • DNS TXT 레코드를 이용하여 인증합니다.
  • 웹 서버 상태와 무관하게 인증 가능합니다.
  • 주로 자동화된 대량 인증, 와일드카드 도메인에 사용합니다.

Nginx에 SSL 설정 적용하기

성공적으로 인증서를 발급받은 후에는 Nginx 설정에 다음과 같이 적용할 수 있습니다.

server {
  listen 443 ssl;
  server_name example.com;

  ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
  ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;

  ...
}

전체 인증 과정 스크립트

위 과정을 압축하여 스크립트로 작성하였습니다.

아래 스크립트는 compose.yaml 파일과 Nginx 설정 파일을 수정하지 않습니다.

그러므로 사용자가 직접 letsencrypt 볼륨을 지정하고 비어 있는 디렉토리를 생성해야 정상적으로 동작합니다. 스크립트가 성공적으로 실행되면 Nginx에 SSL 설정을 직접 적용시켜 주어야 합니다.

Docker compose를 구성한 디렉토리에서 실행 가능한 스크립트입니다.

curl -sL https://git.inas.kr/inas/CertbotWrapper/raw/branch/main/certbot.sh -o certbot.sh
chmod +x certbot.sh
./certbot.sh example.com http

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다