How to handle HTTPS using Nginx, Let's encrypt and Docker

  1. 初始nginx配置可以如下(可以先生成nginx文件夹,再填入以下内容,再)

    docker compose restart or docker compose exec webserver nginx -s reload

    server {
        listen 80;
        listen [::]:80;
    
        server_name hazysite.icu www.hazysite.icu ;
        server_tokens off;
    
        location /.well-known/acme-challenge/ {
            root /var/www/certbot;
        }
    
        location / {
            return 301 https://hazysite.icu$request_uri;
        }
    }
    
  2. docker生成nginx

    services:
      nginx:
        image: nginx:alpine  # 如果使用自定义 Dockerfile,则改为 `build: .`
        container_name: https-nginx
        ports:
          - "80:80"
          - "443:443"   # 开放HTTPS端口
        restart: always
        volumes:
          - ./nginx/conf/:/etc/nginx/conf.d/:ro         # 配置信息,如代理
          - ./nginx/html/:/usr/share/nginx/html/:ro     # 静态网页
          
          - ./certbot/www:/var/www/certbot/:ro          # certbot 
          - ./certbot/conf/:/etc/nginx/ssl/:ro          # SSL
    
      certbot:
        image: certbot/certbot
        container_name: my-certbot
        volumes:
          - ./certbot/www/:/var/www/certbot/:rw
          - ./certbot/conf/:/etc/letsencrypt/:rw
    

    注意,docker 网关只能实现容器互访,宿主机应用访问需要重新走宿主机内网ip ip a | grep inet

    sudo docker compose up -d
    
  3. 测试certbot能否顺利挑战

    sudo docker compose run --rm certbot certonly --webroot --webroot-path=/var/www/certbot/ --dry-run -d hazysite.icu
    

    模拟成功去掉--dry-run 部署ssl证书【nginx存在SSL解析也会报错,可以先将其他conf文件移开】

    sudo docker compose run --rm certbot certonly --webroot --webroot-path=/var/www/certbot/  -d hazysite.icu
    

    注意,如果你在docker-compose.yml给my-certbot提供了循环指令,那么需要使用sudo docker exec -it my-certbot /bin/sh 代替sudo docker compose run --rm certbot 。后者是临时启用一个docker container,前者是进入container的shell。

  4. 修改nginx配置以支持https

    # server https index
    server {
        listen 443 default_server ssl;
        listen [::]:443 ssl;
    
        server_name hazysite.icu;
    
        ssl_certificate /etc/nginx/ssl/live/hazysite.icu/fullchain.pem;
        ssl_certificate_key /etc/nginx/ssl/live/hazysite.icu/privkey.pem;
    
        location / {
            root /usr/share/nginx/html;
            index index.html index.htm;
        }
    }
    

    重启docker 容器

    sudo docker compose restart
    
    nginx -t
    nginx -s reload