Certbot 获取并自动更新 Let's Encrypt SSL 证书

aws云服务器的收费很奇葩:

用 cerbot申请免费证书并自动续期,过程有点复杂。

1.配置nginx,先不要配置SSL证书,因为还没有申请。

   # 网站服务入口
    upstream backend {
      server next-app:3000 fail_timeout=0;
    }
    
    server {
       # listen       443 ssl;
         listen 80;
         listen [::]:80;
         server_name  daism.io;
       # ssl_certificate      /etc/nginx/conf.d/public.pem;
       # ssl_certificate_key  /etc/nginx/conf.d/private.key;
         root /home;
        # 关键步骤,申请证书需要验证.well-known/acme-challenge 
        location /.well-known/acme-challenge/ {
            root /var/www/certbot;
        }
        
        gzip on;
        gzip_disable "msie6";
        gzip_vary on;
        gzip_proxied any;
        gzip_comp_level 6;
        gzip_buffers 16 8k;
        gzip_http_version 1.1;
        gzip_types text/plain text/css application/json 
application/javascript text/xml application/xml
application/xml+rss text/javascript image/svg+xml image/x-icon; location / { try_files $uri @proxy; proxy_connect_timeout 10s; proxy_send_timeout 10s; proxy_read_timeout 10s; client_max_body_size 20M; } location @proxy { proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header Proxy ""; proxy_pass_header Server; proxy_pass http://backend; proxy_buffering on; proxy_redirect off; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_cache_valid 200 7d; proxy_cache_valid 410 24h; proxy_cache_use_stale error timeout updating http_500 http_502
http_503 http_504; add_header X-Cached $upstream_cache_status; tcp_nodelay on; } }

2.docker compose 中配置好volumes和certbot 

services:     
  nginx:
    image: nginx:latest
    container_name: nginx
    ports:
        - "80:80"
        - "443:443"
    volumes:
      - ./data/config/default.conf:/etc/nginx/conf.d/default.conf
      - ./certbot/conf:/etc/letsencrypt   # 与certbot 共享宿主文件
      - ./certbot/www:/var/www/certbot    # 与certbot 共享宿主文件      
      - ./data/html:/usr/share/nginx/html 
      - ./data/images:/home
    depends_on:
      - next-app
      - certbot  # 依赖于certbot 容器
    networks:
      - dev_network
          
  certbot:
    image: certbot/certbot
    logging:
      driver: "json-file"
      options:
        max-size: "5m"
        max-file: "2"
    container_name: certbot
    volumes:
      - ./certbot/www:/var/www/certbot   # 与nginx 共享宿主文件
      - ./certbot/conf:/etc/letsencrypt  # 与nginx 共享宿主文件
      # 证书申请成功后,重启nginx
      - ./scripts/reload-nginx.sh:/scripts/reload-nginx.sh 
      # 隔12小时试重新申请证书,证书申请成功后,调用脚本重启nginx
    entrypoint:  "/bin/sh -c 'trap exit TERM; while :; do echo \"[Certbot] \
      Trying renewal at $(date)\";certbot renew --webroot -w /var/www/certbot\ 
      --quiet --deploy-hook \"/scripts/reload-nginx.sh\" && echo \"[Certbot]\
      Renewal attempt complete at $(date)\"; sleep 12h & wait $${!}; done'"
    restart: always
    networks:
      - dev_network

nginx 重新启动脚本:

# !/bin/bash
docker exec nginx nginx -s reload


3.启动docker compose并申请证书

docker run --rm \
    -v "$(pwd)/certbot/conf:/etc/letsencrypt" \
    -v "$(pwd)/certbot/www:/var/www/certbot" \
    certbot/certbot certonly \
    --webroot -w /var/www/certbot \
    -d daism.io -d www.daism.io\
    --email 393909065@qq.com --agree-tos --no-eff-email

4. 证书申请成功后,重新配置 nginx的default.conf

# 网站服务入口
    upstream backend {
      server next-app:3000 fail_timeout=0;
    }
    server {
      listen 80;
      listen [::]:80;
      server_name daism.io;
      root /home;
      # 强制切换到https 
      location / { return 301 https://$host$request_uri; }
    }
    
    server {
         listen       443 ssl;
         listen 80;
         listen [::]:80;
         server_name  daism.io;
         ssl_certificate      /etc/letsencrypt/live/daism.io/fullchain.pem;
         ssl_certificate_key   /etc/letsencrypt/live/daism.io/privkey.pem;
         root /home;
        # 关键步骤,申请证书需要验证.well-known/acme-challenge 
        location /.well-known/acme-challenge/ {
            root /var/www/certbot;
        }
        
        gzip on;
        gzip_disable "msie6";
        gzip_vary on;
        gzip_proxied any;
        gzip_comp_level 6;
        gzip_buffers 16 8k;
        gzip_http_version 1.1;
        gzip_types text/plain text/css application/json 
application/javascript text/xml application/xml
application/xml+rss text/javascript image/svg+xml image/x-icon; location / { try_files $uri @proxy; proxy_connect_timeout 10s; proxy_send_timeout 10s; proxy_read_timeout 10s; client_max_body_size 20M; } location @proxy { proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header Proxy ""; proxy_pass_header Server; proxy_pass http://backend; proxy_buffering on; proxy_redirect off; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_cache_valid 200 7d; proxy_cache_valid 410 24h; proxy_cache_use_stale error timeout updating http_500 http_502
http_503 http_504; add_header X-Cached $upstream_cache_status; tcp_nodelay on; } }

3. 重新 启动docker compose 可以使用https 访问