SSL Certificate ด้วย Let’s Encrypt และ Certbot ใน Docker

แม้ Nginx Proxy Manager และ Traefik จะจัดการ SSL อัตโนมัติให้แล้ว แต่ในบางครั้งคุณอาจต้องการจัดการ SSL Certificate เองโดยใช้ Certbot ซึ่งเป็นเครื่องมืออ้างอิง Let’s Encrypt อย่างเป็นทางการ บทความนี้จะอธิบายวิธีออก Certificate โดยใช้ Certbot Container และตั้งค่า Auto-renewal

Let’s Encrypt และ Certbot คืออะไร?

Let’s Encrypt คือ Certificate Authority (CA) ที่ให้บริการ SSL Certificate ฟรี และอัตโนมัติ Certbot คือ Client Tool สำหรับติดต่อกับ Let’s Encrypt เพื่อขอ, ต่ออายุ และจัดการ Certificate Certificate มีอายุ 90 วัน แต่ Certbot จะ Renew อัตโนมัติเมื่อเหลือน้อยกว่า 30 วัน

สถานการณ์ที่ควรใช้ Certbot ตรงๆ

  • ใช้ Nginx โดยตรง (ไม่ใช้ NPM หรือ Traefik)
  • ต้องการควบคุม Certificate เองเต็มที่
  • ใช้ Wildcard Certificate (*.example.com)
  • เชื่อมต่อกับระบบ เช่น HAProxy หรือ Custom Load Balancer

วิธีที่ 1: Certbot แบบ Standalone

วิธีนี้ Certbot จะรัน Web Server ชั่วคราวบน Port 80 เพื่อยืนยัน Domain:

# หยุด Web Server ที่ใช้ Port 80 ก่อนเสมอ
docker compose stop

# รัน Certbot เพื่อออก Certificate
docker run --rm \
  -p 80:80 \
  -v /etc/letsencrypt:/etc/letsencrypt \
  certbot/certbot certonly \
  --standalone \
  --email [email protected] \
  --agree-tos \
  --no-eff-email \
  -d example.com \
  -d www.example.com

วิธีที่ 2: Certbot แบบ Webroot (ไม่หยุด Web Server)

วิธีนี้เหมาะเมื่อ Web Server รันอยู่แล้ว โดยให้ Certbot วางไฟล์ Challenge ใน Web Root:

version: '3.8'

services:
  nginx:
    image: nginx:alpine
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./nginx.conf:/etc/nginx/conf.d/default.conf
      - certbot_www:/var/www/certbot
      - certbot_conf:/etc/letsencrypt
    networks:
      - web_network

  certbot:
    image: certbot/certbot
    volumes:
      - certbot_www:/var/www/certbot
      - certbot_conf:/etc/letsencrypt
    entrypoint: "/bin/sh -c 'trap exit TERM; while :; do certbot renew; sleep 12h & wait $${!}; done;'"

volumes:
  certbot_www:
  certbot_conf:

networks:
  web_network:

ไฟล์ nginx.conf จัดการ Challenge Path:

server {
    listen 80;
    server_name example.com www.example.com;

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

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

server {
    listen 443 ssl;
    server_name example.com www.example.com;

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

    location / {
        proxy_pass http://your-app:8080;
    }
}

ออก Certificate ครั้งแรก

# ออก Certificate ครั้งแรก
docker compose run --rm certbot certonly \
  --webroot \
  --webroot-path=/var/www/certbot \
  --email [email protected] \
  --agree-tos \
  --no-eff-email \
  -d example.com \
  -d www.example.com

# เริ่ม Nginx + Certbot
docker compose up -d

Auto-renewal

Certbot Container ที่ตั้งค่าด้านบนจะรันคำสั่ง certbot renew ทุก 12 ชั่วโมง โดยอัตโนมัติ เมื่อ Certificate เหลือน้อยกว่า 30 วัน จะต่ออายุทันที

หลัง Renew ให้สั่งให้ Nginx โหลด Config ใหม่:

# สั่ง Nginx โหลด Config (หลัง Renew Certificate)
docker compose exec nginx nginx -s reload

เปรียบเทียบ: Certbot vs NPM vs Traefik

วิธี ความยาก เหมาะสำหรับ
Nginx Proxy Manager ง่ายมาก ผู้เริ่มต้น, VPS ทั่วไป
Traefik ปานกลาง DevOps, Microservices
Certbot + Nginx ยาก ต้องควบคุมเต็มที่, Wildcard SSL

สรุป

แนวคิด รายละเอียด
Certbot Standalone หยุด Web Server + ออก Certificate
Certbot Webroot ไม่หยุด Web Server ผ่าน Challenge File
Auto-renewal Certbot Container รันเบ้ากระเงิน ต่ออายุอัตโนมัติ
Certificate อายุ 90 วัน (ต่ออายุเมื่อเหลือ 30 วัน)

ขอแสดงความยินดี! คุณได้เรียนรู้ชุด Reverse Proxy & SSL ครบทั้ง 5 บทความแล้ว ตั้งแต่แนวคิดพื้นฐาน จนถึงการติดตั้ง NPM, Traefik และ Certbot บทความชุดถัดไปจะเป็นชุด Use Case ซึ่งจะแสดงตัวอย่างการนำ Docker ไปใช้ในโลกจริง