服务器上,使用Docker Compose部署和管理各种服务,体验相当好。部署Certbot,申请和更新免费SSL证书,有些不同,记录一下相关操作。
首先,很多DNS服务商已经在提供DNS服务的同时,提供了免费SSL服务。如果这种服务能解决SSL免费证书的需求,就没必要部署Certbot了。例如Cloudflare、DNSPod等。
使用Docker Compose部署Certbot的特点:
- Docker Compose部署和管理容器,比较清晰和方便。
- 比如直接运行容器(即使用
docker run
命令运行容器),能记录容器的配置,方便查看和维护。
- 比如直接运行容器(即使用
- Certbot容器无需一直保持运行,只需启动一下,申请或续签SSL免费证书。
- 只要得到SSL免费证书的文件,即可停止运行。
- 需要设置定时运行,执行续签证书。
- 需要使用SSL免费证书的服务(例如Nginx),需要把证书文件
mount
到对应的容器。
1. Docker Compose部署Certbot
创建好部署目录,以下例子采用/opt/docker/certbot
。
先创建Cloudflare的认证配置文件:/opt/docker/certbot/etc/letsencrypt/certbot-dns-cloudflare-credentials.ini
。该文件格式如下:
dns_cloudflare_api_token=<your-cloudflare-api-token>
注意,/opt/docker/certbot/etc/letsencrypt
最好设置拥有者为root
用户,并保证只有root
可读写,提高安全性。
sudo chown -R root:root /opt/docker/certbot/etc/letsencrypt
再创建docker-compose.yaml
文件,该文件内容如下:
# https://hub.docker.com/r/certbot/dns-cloudflare
services:
certbot:
image: certbot/dns-cloudflare:latest
volumes:
- ./etc/letsencrypt:/etc/letsencrypt
- ./log:/var/log/letsencrypt
command: certonly --agree-tos --non-interactive -m xxx@abc.com --dns-cloudflare --dns-cloudflare-credentials /etc/letsencrypt/certbot-dns-cloudflare-credentials.ini -d example.com,*.example.com
networks:
default:
name: default-net
external: true
注意:
- 由于采用Cloudflare的DNS服务,所以采用
dns-cloudflare
的Docker镜像。 --agree-tos
,同意ACME订阅协议(the ACME server’s Subscriber Agreement)--non-interactive
,非交互式运行,即运行过程中不需要询问用户输入。- 当客户端发现参数缺失时会给出相应的说明。
-m
,即--email
,设置域名所有者的EMail。-d
,设置SSL证书相关域名。- 多个域名可以设置多个
-d
实现。 - 也可以1个
-d
设置多个域名,但域名之间需要英文逗号(,)分隔,并且主域名放第一位,子域名随后。 - 支持泛域名,即
*.
+主域名,避免设置多个子域名。
- 多个域名可以设置多个
- 最后的
networks
可以不设。- 这里设置了默认加入网络
default-net
,方便通过网络访问其它容器。
- 这里设置了默认加入网络
最后启动。由于无需一直保持运行,所以不用添加-d
参数。如果无错误输出,则成功运行。
docker compose up
2. 使用SSL证书
对于HTTP服务的容器,只需把SSL证书文件mount
到相关容器即可。
比如Nginx,其docker-compose.yaml
的volumes
配置如下:
volumes:
- ../certbot/etc/letsencrypt/archive:/etc/letsencrypt/archive:ro
- ../certbot/etc/letsencrypt/live:/etc/letsencrypt/live:ro
对应网站的server
配置SSL证书:
server {
server_name example.com;
listen 443 ssl;
...
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
...
3. 自动续签
这里使用Systemd Timer实现定时自动renew证书。
创建服务管理单元,文件/opt/docker/certbot/deploy_conf/certbot-renew.service
:
[Unit]
Description=Certbot renew
Requires=network-online.target
[Service]
Type=oneshot
ExecStart=docker compose -f /opt/docker/certbot/docker-compose.yaml start
[Install]
WantedBy=multi-user.target
创建定时器单元,文件/opt/docker/certbot/deploy_conf/certbot-renew.timer
:
[Unit]
Description=Auto run certbot renew
Requires=certbot-renew.service
[Timer]
# 周一和周四的凌晨3点执行
OnCalendar=Mon,Thu *-*-* 03:00:00
# 在5分钟以内,随机延迟执行
RandomizedDelaySec=5min
Unit=certbot-renew.service
[Install]
WantedBy=multi-user.target
部署:
sudo ln -s /opt/docker/certbot/deploy_conf/certbot-renew.service /etc/systemd/system/certbot-renew.service
sudo ln -s /opt/docker/certbot/deploy_conf/certbot-renew.timer /etc/systemd/system/certbot-renew.timer
sudo systemctl daemon-reload
sudo systemctl enable certbot-renew.timer
sudo systemctl start certbot-renew.timer
注意:这里没实现自动续签成功后(即SSL证书文件更新后),自动更新Nginx。