gongdear

gongdear的技术博客

欢迎大家参观我的博客
  menu
103 文章
89355 浏览
0 当前访客
ღゝ◡╹)ノ❤️

docker-compose部署acme自动更新nginx中证书

快速部署docker acme nginx

这里推荐一下我基于官方docker nginx编译添加模块的NGINX,可以直接开启brotli 压缩。

https://github.com/SuperNG6/docker-nginx

具体如何操作我写在了注释里,非常简单,唯一需要注意的一点就是,在还未生成证书之前,不要修改NGINX配置文件 ,以免NGINX不停报错重启。

*** deployId相关配置详见这里: https://docs.certcloud.cn/docs/installation/auto/acme/acmesh/

这里推荐使用dns验证,可以不占用80端口

version: '3.1'
services:
  nginx:
    image: superng6/nginx:debian-stable-1.18.0
    container_name: docker_nginx
    restart: unless-stopped
    network_mode: host
    labels: 
      - 'docker_nginx'
    volumes:
      - /usr/share/zoneinfo/Asia/Shanghai:/etc/localtime:ro
      - /var/www/html:/var/www/html
      - /root/nginx/nginx.conf:/etc/nginx/nginx.conf
      - /root/nginx/conf.d:/etc/nginx/conf.d
      - /root/nginx/ssl:/etc/nginx/ssl
      - /root/nginx/logs:/var/log/nginx
 
  acme:
    image: neilpang/acme.sh
    container_name: acme
    restart: unless-stopped
    environment:
      DP_Id: '这里填dnspod id'
      DP_Key: '这里填dnspod key'
      DEPLOY_DOCKER_CONTAINER_LABEL: 'docker_nginx'
      DEPLOY_DOCKER_CONTAINER_KEY_FILE: '/etc/nginx/ssl/all.sleele.com/sleele.com.key'
      DEPLOY_DOCKER_CONTAINER_FULLCHAIN_FILE: '/etc/nginx/ssl/all.sleele.com/fullchain.cer'
      DEPLOY_DOCKER_CONTAINER_RELOAD_CMD: 'nginx -s reload'
    volumes:
      - /usr/share/zoneinfo/Asia/Shanghai:/etc/localtime:ro
      - /var/run/docker.sock:/var/run/docker.sock:ro
      - /root/nginx/acme.sh:/acme.sh
      - /root/nginx/ssl:/etc/nginx/ssl
    command: daemon
    # 首次运行先进入容器生成证书
    # acme.sh --issue --dns dns_dp -d sleele.com -d *.sleele.com
    # docker exec -i acme acme.sh --issue --dns dns_dp -d sleele.com -d *.sleele.com
    # 然后部署证书到指定文件夹
    # acme.sh --deploy -d sleele.com --deploy-hook docker
    # docker exec -i acme acme.sh --deploy -d sleele.com --deploy-hook docker

2022.03.21更新 acme换用zero ssl 首次使用需注册邮箱
初撰本文时,acme还没有使用zero ssl,随着版本迭代,acme.sh换用了zero ssl,首次使用必须要注册邮箱才可以

初撰本文时,acme还没有使用zero ssl,随着版本迭代,acme.sh换用了zero ssl,首次使用必须要注册邮箱才可以

 docker exec -i acme-rsa acme.sh --register-account -m my@example.com   

首次运行先生成泛域名证书,然后再部署证书

docker exec -i acme acme.sh --issue --dns dns_dp -d 你的域名.com -d *.你的域名.com   
docker exec -i acme acme.sh --deploy -d 你的域名.com --deploy-hook docker   

所有二级域名都可以使用这个证书,所以NGINX里每个站点的配置文件都指向这个证书就可以了

NGINX HTTPS CONF

这里给两个,一个反向代理,一个正向代理。

反向代理

# generated 2021-03-27, Mozilla Guideline v5.6, nginx 1.18.0, OpenSSL 1.1.1d, intermediate configuration
# https://ssl-config.mozilla.org/#server=nginx&version=1.18.0&config=intermediate&openssl=1.1.1d&guideline=5.6
server {
    listen 80;
    listen [::]:80;
    server_name 你到域名;
    return 301 https://$host$request_uri;
}
 
server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    server_name 你到域名;
    location / {
        proxy_pass http://你要反代的ip:端口;
        proxy_redirect off;
        # 保证获取到真实IP
        proxy_set_header X-Real-IP $remote_addr;
        # 真实端口号
        proxy_set_header X-Real-Port $remote_port;
        # X-Forwarded-For 是一个 HTTP 扩展头部。
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        # 在多级代理的情况下,记录每次代理之前的客户端真实ip 
        proxy_set_header HTTP_X_FORWARDED_FOR $remote_addr;
        # 获取到真实协议
        proxy_set_header X-Forwarded-Proto $scheme;
        # 真实主机名
        proxy_set_header Host $host;
        # 设置变量
        proxy_set_header X-NginX-Proxy true;
        # 开启 brotli
        proxy_set_header Accept-Encoding "";
    }   
 
    # 日志
	access_log /var/log/nginx/access.log;
	error_log /var/log/nginx/error.log;
    # 证书
    ssl_certificate /etc/nginx/ssl/all.sleele.com/fullchain.cer;
    ssl_certificate_key /etc/nginx/ssl/all.sleele.com/sleele.com.key;
 
    # curl https://ssl-config.mozilla.org/ffdhe2048.txt > /path/to/dhparam
    ssl_dhparam /etc/nginx/ssl/dhparam;
 
    # HSTS (ngx_http_headers_module is required) (63072000 seconds)
    add_header Strict-Transport-Security "max-age=63072000" always;
 
    # OCSP stapling
    ssl_stapling on;
    ssl_stapling_verify on;
 
    # verify chain of trust of OCSP response using Root CA and Intermediate certs
    ssl_trusted_certificate  /etc/nginx/ssl/all.sleele.com/fullchain.cer;
    # replace with the IP address of your resolver
    resolver 223.5.5.5;
    resolver_timeout 5s;
}

正向代理

# generated 2021-03-27, Mozilla Guideline v5.6, nginx 1.18.0, OpenSSL 1.1.1d, intermediate configuration
# https://ssl-config.mozilla.org/#server=nginx&version=1.18.0&config=intermediate&openssl=1.1.1d&guideline=5.6
server {
    listen 80;
    listen [::]:80;
    server_name tk.sleele.com;
    return 301 https://$host$request_uri;
}
 
server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    server_name tk.sleele.com;
    location / {
        root /var/www/html/aria2-trackers;
        index index.html;
    }
 
    # 日志
	access_log /var/log/nginx/tk-access.log;
	error_log /var/log/nginx/tk-error.log;
 
    # 证书
    ssl_certificate /etc/nginx/ssl/all.sleele.com/fullchain.cer;
    ssl_certificate_key /etc/nginx/ssl/all.sleele.com/sleele.com.key;
 
    # curl https://ssl-config.mozilla.org/ffdhe2048.txt > /path/to/dhparam
    ssl_dhparam /etc/nginx/ssl/dhparam;
 
    # HSTS (ngx_http_headers_module is required) (63072000 seconds)
    add_header Strict-Transport-Security "max-age=63072000" always;
 
    # OCSP stapling
    ssl_stapling on;
    ssl_stapling_verify on;
 
    # verify chain of trust of OCSP response using Root CA and Intermediate certs
    ssl_trusted_certificate  /etc/nginx/ssl/all.sleele.com/fullchain.cer;
    # replace with the IP address of your resolver
    resolver 223.5.5.5;
    resolver_timeout 5s;
}

nginx.conf

load_module /usr/local/nginx/modules/ngx_http_brotli_filter_module.so;
load_module /usr/local/nginx/modules/ngx_http_brotli_static_module.so;
load_module /usr/local/nginx/modules/ngx_http_cache_purge_module.so;
 
user www-data;
worker_processes auto;
pid /run/nginx.pid;
include /etc/nginx/modules-enabled/*.conf;
 
events {
	worker_connections 768;
	# multi_accept on;
}
 
http {
 
	##
	# Basic Settings
	##
 
	sendfile on;
	tcp_nopush on;
	tcp_nodelay on;
	keepalive_timeout 65;
	types_hash_max_size 2048;
	# server_tokens off;
 
	# server_names_hash_bucket_size 64;
	# server_name_in_redirect off;
 
	include /etc/nginx/mime.types;
	default_type application/octet-stream;
 
	##
	# SSL Settings
	##
	ssl_session_cache   shared:SSL:50m; # speed up first time. 1m ~= 4000 connections
    ssl_session_timeout 1d;
	ssl_session_tickets off;
	ssl_protocols TLSv1.1 TLSv1.2 TLSv1.3; # Dropping SSLv1, ref: POODLE
	ssl_prefer_server_ciphers on;
        ssl_ciphers         'TLS13-AES-256-GCM-SHA384:TLS13-CHACHA20-POLY1305-SHA256:TLS13-AES-128-GCM-SHA256:TLS13-AES-128-CCM-8-SHA256:TLS13-AES-128-CCM-SHA256:EECDH+CHACHA20:EECDH+CHACHA20-draft:EECDH+ECDSA+AES128:EECDH+aRSA+AES128:RSA+AES128:EECDH+ECDSA+AES256:EECDH+aRSA+AES256:RSA+AES256:EECDH+ECDSA+3DES:EECDH+aRSA+3DES:RSA+3DES:!MD5';	ssl_prefer_server_ciphers on;
 
 
	ssl_buffer_size 4k;
	##
	# Logging Settings
	##
 
	access_log /var/log/nginx/access.log;
	error_log /var/log/nginx/error.log;
 
	##
	# Gzip Settings
	##
 
    client_max_body_size 2048M;
    proxy_max_temp_file_size 2048M; 
 
	# Enable Gzip compression
	gzip          on;
 
	# Compression level (1-9)
	gzip_comp_level     5;
	gzip_static on;
 
	# Don't compress anything under 256 bytes
	gzip_min_length     256;
 
	# Compress output of these MIME-types
	gzip_types
		application/atom+xml
		application/javascript
		application/json
		application/rss+xml
		application/vnd.ms-fontobject
		application/x-font-ttf
		application/x-font-opentype
		application/x-font-truetype
		application/x-javascript
		application/x-web-app-manifest+json
		application/xhtml+xml
		application/xml
		font/eot
		font/opentype
		font/otf
		image/svg+xml
		image/x-icon
		image/vnd.microsoft.icon
		text/css
		text/plain
		text/javascript
		text/x-component;
 
# Disable gzip for bad browsers
	gzip_disable  "MSIE [1-6]\.(?!.*SV1)";
 
    brotli on;
    brotli_comp_level 5; 
	brotli_static on;
    brotli_types
		application/atom+xml
		application/javascript
		application/json
		application/rss+xml
		application/vnd.ms-fontobject
		application/x-font-ttf
		application/x-font-opentype
		application/x-font-truetype
		application/x-javascript
		application/x-web-app-manifest+json
		application/xhtml+xml
		application/xml
		font/eot
		font/opentype
		font/otf
		image/svg+xml
		image/x-icon
		image/vnd.microsoft.icon
		text/css
		text/plain
		text/javascript
		text/x-component;
 
 
	##
	# Virtual Host Configs
	##
 
	include /etc/nginx/conf.d/*.conf;
	include /etc/nginx/sites-enabled/*;

}

推荐设置

为了让NGINX的使用体验更接近宿主机上的nginx,建议设置别名,这样就和本机安装的NGINX使用起来无异了

sudo vim ~/.bashrc
# 添加如下内容,保存
alias nginx='docker exec -i docker_nginx nginx'   

查看效果

部署完证书后,就可以修改NGINX配置文件了,之后 nginx -s reload,查看效果

XJuG6B

4uSOJi

之后就就不用再理会了,证书快到期后会自动续订,并重载NGINX

2022.03.21更新 ACME ECC RSA双证书

介绍就不多说了,ECC更快更节能,兼容性方面,在2022这个节点,已经没有任何问题了,不过为了保险还是双证书吧

注意:第一次需要用,需要用自己的邮箱注册 zero ssl

 docker exec -i acme-ecc acme.sh --register-account -m my@example.com   
 docker exec -i acme-rsa acme.sh --register-account -m my@example.com 

先部署acme容器后,再执行上面👆🏻的操作

version: "3.4"
services:
  nginx:
    image: superng6/nginx:stable-1.20.2
    container_name: docker_nginx
    restart: unless-stopped
    network_mode: host
    labels:
      - "docker_nginx"
    volumes:
      - /usr/share/zoneinfo/Asia/Shanghai:/etc/localtime:ro
      - /root/nginx/www/html:/var/www/html
      - /root/nginx/nginx.conf:/etc/nginx/nginx.conf
      - /root/nginx/conf.d:/etc/nginx/conf.d
      - /root/nginx/ssl:/etc/nginx/ssl
      - /root/nginx/logs:/var/log/nginx
 
  acme-rsa:
    image: neilpang/acme.sh
    container_name: acme-rsa
    restart: unless-stopped
    environment:
      DP_Id: "*"
      DP_Key: "*"
      DEPLOY_DOCKER_CONTAINER_LABEL: "docker_nginx"
      DEPLOY_DOCKER_CONTAINER_KEY_FILE: "/etc/nginx/ssl/all.sleele.com/sleele.com.key"
      DEPLOY_DOCKER_CONTAINER_FULLCHAIN_FILE: "/etc/nginx/ssl/all.sleele.com/fullchain.cer"
      DEPLOY_DOCKER_CONTAINER_RELOAD_CMD: "nginx -s reload"
    volumes:
      - /usr/share/zoneinfo/Asia/Shanghai:/etc/localtime:ro
      - /var/run/docker.sock:/var/run/docker.sock:ro
      - /root/nginx/acme.sh:/acme.sh
      - /root/nginx/ssl:/etc/nginx/ssl
    command: daemon
  # 首次运行先进入容器生成证书
  # docker exec -i acme-rsa acme.sh --issue --dns dns_dp -d sleele.com -d *.sleele.com
  # 然后部署证书到制定文件夹
  # acme.sh --deploy -d sleele.com --deploy-hook docker
  # docker exec -i acme-rsa acme.sh --deploy -d sleele.com --deploy-hook docker
 
 
  acme-ecc:
    image: neilpang/acme.sh
    container_name: acme-ecc
    restart: unless-stopped
    environment:
      DP_Id: "*"
      DP_Key: "*"
      DEPLOY_DOCKER_CONTAINER_LABEL: "docker_nginx"
      DEPLOY_DOCKER_CONTAINER_KEY_FILE: "/etc/nginx/ssl/all.sleele.com.ecc/sleele.com.key"
      DEPLOY_DOCKER_CONTAINER_FULLCHAIN_FILE: "/etc/nginx/ssl/all.sleele.com.ecc/fullchain.cer"
      DEPLOY_DOCKER_CONTAINER_RELOAD_CMD: "nginx -s reload"
    volumes:
      - /usr/share/zoneinfo/Asia/Shanghai:/etc/localtime:ro
      - /var/run/docker.sock:/var/run/docker.sock:ro
      - /root/nginx/acme.sh.ecc:/acme.sh
      - /root/nginx/ssl:/etc/nginx/ssl
    command: daemon
    # 首次运行先进入容器生成证书
    # acme.sh --issue --dns dns_dp -d sleele.com -d *.sleele.com
    # 第一次需要用自己的邮箱注册 docker exec -i acme-ecc acme.sh --register-account -m my@example.com
    # docker exec -i acme-ecc acme.sh --issue --dns dns_dp -d sleele.com -d *.sleele.com --keylength ec-256
    # 然后部署证书到指定文件夹
    # acme.sh --deploy -d sleele.com --deploy-hook docker
    # docker exec -i acme-ecc acme.sh --deploy -d sleele.com --ecc --deploy-hook docker

参考资料

acme deploy-to-docker-containers

https://github.com/acmesh-official/acme.sh/wiki/deploy-to-docker-containers

Docker 下,a container to another container 的部署方式结果与配置不一致

https://github.com/acmesh-official/acme.sh/issues/2400

https://sleele.com/2021/04/15/docker-acme-with-docker-nginx/

宝剑锋从磨砺出,梅花香自苦寒来.