Setup Let's Encrypt กับ nGINX
Reference: https://pentacent.medium.com/nginx-and-lets-encrypt-with-docker-in-less-than-5-minutes-b4b8a60d3a71
Setup certbot กับ nginx
เราจะต้องมี certbot
runคู่กับ nginx ก่อน certbot เป็น tool ของ Electronic Frontier Foundation สำหรับจัดการ Let's Encrypt certificates
สังเกตุว่ามีการ mapping volumes ของทั้ง nginx
และ certbot
ให้ shared กันด้วย
Add "acme-challenge" path
เพิ่ม section ต่อไปนี้ลงใน server
section ของ service ที่เราต้องการให้มี certificate แต่เป็น port 80!
location /.well-known/acme-challenge/ {
root /var/www/certbot;
}
เช่น
server {
rewrite_log off;
listen 80;
charset utf-8;
server_name example.org;
client_max_body_size 1m;
location / {
return 301 https://$host$request_uri;
}
location /.well-known/acme-challenge/ {
root /var/www/certbot;
}
}
จากนั้นเพิ่ม section นี้ลงใน server
ที่เป็น port 443! สังเกตุว่าตรง URL จะมีชื่อ domain ของเราอยู่ด้วย (ในที่นี้คือ example.org
) ต้องแก้ให้ตรงกับ domain ที่เราจะขอ
ssl_certificate /etc/letsencrypt/live/example.org/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.org/privkey.pem;
และ (optional) best-practice HTTPS configuration ของ Let's Encrypt เอง
include /etc/letsencrypt/options-ssl-nginx.conf;
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
เช่น
server {
rewrite_log off;
listen 443 ssl http2;
charset utf-8;
server_name example.org;
location / {
root /app;
index home.html;
}
ssl_certificate /etc/letsencrypt/live/example.org/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.org/privkey.pem;
include /etc/letsencrypt/options-ssl-nginx.conf;
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
}
Create dummy certificate to start nginx
มี script สำหรับสร้าง dummy certificate (เป็น bash
) download ได้จาก
curl -L https://raw.githubusercontent.com/wmnnd/nginx-certbot/master/init-letsencrypt.sh > init-letsencrypt.sh
แต่ต้องแก้ file init-letsencrypt.sh
ก่อน มี 3 fields ที่ต้องแก้คือ
domains=(site.yourdomain.uri)
data_path="/data/certbot" # certbot shared path
email="admin@yourdomain.uri" # valid email address
Note: ถึงแม้ว่า domains
จะเป็น array แต่ควรทำทีละ site เพราะเคยเจอปัญหาทำหลายๆอันแล้ว script มัน run ไม่ถูก
run init-letsencrypt.sh
เพื่อ start nginx และ download certificate จาก Let's Encrypt!
Auto renewal
เพิ่ม script ดังต่อไปนี้ที่ certbot
เพื่อให้ check certificate renewal ทุกๆ 12 ชั่วโมง (ตามคำแนะนำของ Let's Encrypt)
entrypoint: "/bin/sh -c 'trap exit TERM; while :; do certbot renew; sleep 12h & wait $${!}; done;'"
และเพิ่ม script นี้ใน nginx
เพื่อให้ nginx reload config ทุกๆ 6 ชั่วโมง
command: "/bin/sh -c 'while :; do sleep 6h & wait $${!}; nginx -s reload; done & nginx -g \"daemon off;\"'"
docker-compose.yml
สุดท้าย หน้าตาประมาณนี้
version: '3'
services:
nginx:
image: nginx:1.15-alpine
ports:
- "80:80"
- "443:443"
volumes:
- ./data/nginx:/etc/nginx/conf.d
- ./data/certbot/conf:/etc/letsencrypt
- ./data/certbot/www:/var/www/certbot
command: "/bin/sh -c 'while :; do sleep 6h & wait $${!}; nginx -s reload; done & nginx -g \"daemon off;\"'"
certbot:
image: certbot/certbot
volumes:
- ./data/certbot/conf:/etc/letsencrypt
- ./data/certbot/www:/var/www/certbot
entrypoint: "/bin/sh -c 'trap exit TERM; while :; do certbot renew; sleep 12h & wait $${!}; done;'"