简介:本文详细介绍如何在Docker环境下使用Certbot获取Let's Encrypt免费SSL证书,并配置自动续期机制,保障HTTPS服务长期安全稳定运行。
在Web服务安全领域,SSL/TLS证书已成为标配。它不仅能加密数据传输、防止中间人攻击,还能提升网站在搜索引擎中的可信度。然而,传统证书管理存在三大痛点:
针对这些问题,Let’s Encrypt提供的免费证书与Certbot自动化工具成为理想解决方案。尤其在Docker环境下,通过容器化部署Certbot,可实现跨平台、可复用的证书管理流程。本文将详细拆解这一过程的实现细节。
Certbot官方提供多种Docker镜像,核心区别如下:
| 镜像名称 | 特点 | 适用场景 |
|————-|———|—————|
| certbot/certbot | 基础镜像,仅含Certbot核心功能 | 简单域名证书获取 |
| certbot/dns-xxx | 集成特定DNS提供商API(如cloudflare、route53) | 需要DNS验证的场景 |
| certbot/certbot:dns-xxx-slim | 精简版DNS验证镜像 | 资源受限环境 |
推荐实践:
对于大多数Web服务,优先使用certbot/certbot基础镜像。若域名使用Cloudflare/AWS Route53等DNS服务,可选择对应DNS镜像简化验证流程。
这是最通用的验证方式,通过在网站根目录放置验证文件证明域名所有权。
创建临时Web目录:
mkdir -p /tmp/certbot/www
启动Certbot容器:
docker run -it --rm \-v "/tmp/certbot/etc:/etc/letsencrypt" \-v "/tmp/certbot/www:/var/www/certbot" \certbot/certbot certonly \--webroot -w /var/www/certbot \-d example.com -d www.example.com \--email admin@example.com \--agree-tos \--no-eff-email
参数解析:
-v:挂载配置目录和Web目录(实现持久化)--webroot:指定验证文件存放路径-d:指定要申请证书的域名--email:接收重要通知的邮箱--agree-tos:自动同意服务条款验证结果:
成功后会生成/tmp/certbot/etc/live/example.com/目录,包含以下关键文件:
fullchain.pem:完整证书链(含中间证书)privkey.pem:私钥文件cert.pem:仅域名证书当服务器无法开放80端口时,可通过DNS记录验证域名所有权。
获取Cloudflare API Token:
Zone:Read和DNS:Edit权限的Token启动DNS验证容器:
docker run -it --rm \-v "/tmp/certbot/etc:/etc/letsencrypt" \-e "CF_API_TOKEN=your_token_here" \certbot/dns-cloudflare certonly \-d example.com \--dns-cloudflare \--dns-cloudflare-credentials /etc/letsencrypt/cloudflare.ini \--email admin@example.com \--agree-tos
关键点:
cloudflare.ini文件(通过卷挂载或环境变量传递)Let’s Encrypt证书有效期仅90天,必须建立自动续期流程。
docker run -it --rm \-v "/tmp/certbot/etc:/etc/letsencrypt" \-v "/tmp/certbot/www:/var/www/certbot" \certbot/certbot renew \--webroot -w /var/www/certbot
创建续期脚本(/usr/local/bin/certbot-renew.sh):
#!/bin/bashdocker run --rm \-v "/tmp/certbot/etc:/etc/letsencrypt" \-v "/tmp/certbot/www:/var/www/certbot" \certbot/certbot renew --quiet --no-self-upgrade# 重启依赖证书的服务(如Nginx)docker restart nginx
添加Cron任务:
crontab -e
添加以下行(每天凌晨3点检查续期):
0 3 * * * /usr/local/bin/certbot-renew.sh >> /var/log/certbot-renew.log 2>&1
强制测试续期流程:
docker run --rm \-v "/tmp/certbot/etc:/etc/letsencrypt" \certbot/certbot renew --dry-run
看到Congratulations, all renewals succeeded表示配置正确。
对于复杂项目,建议通过docker-compose.yml管理Certbot服务:
version: '3.8'services:certbot:image: certbot/certbotcontainer_name: certbotvolumes:- ./certbot/etc:/etc/letsencrypt- ./certbot/www:/var/www/certbotcommand: certonly --webroot -w /var/www/certbot -d example.com --email admin@example.com --agree-tos --no-eff-email# 或使用DNS验证# environment:# - CF_API_TOKEN=xxx# command: certonly --dns-cloudflare -d example.com --dns-cloudflare-credentials /etc/letsencrypt/cloudflare.ini --email admin@example.com --agree-tosnginx:image: nginx:latestports:- "80:80"- "443:443"volumes:- ./nginx/conf:/etc/nginx/conf.d- ./certbot/etc/live/example.com/fullchain.pem:/etc/nginx/ssl/fullchain.pem- ./certbot/etc/live/example.com/privkey.pem:/etc/nginx/ssl/privkey.pemdepends_on:- certbot
通过单个命令申请多个域名证书:
docker run -it --rm \-v "/tmp/certbot/etc:/etc/letsencrypt" \certbot/certbot certonly \--webroot -w /var/www/certbot \-d example.com -d www.example.com -d api.example.com \--email admin@example.com \--agree-tos
docker run -it --rm \-v "/tmp/certbot/etc:/etc/letsencrypt" \-e "CF_API_TOKEN=your_token" \certbot/dns-cloudflare certonly \--dns-cloudflare \-d "*.example.com" \--email admin@example.com \--agree-tos
建议配置监控系统检查证书过期时间:
# 检查证书剩余天数openssl x509 -in /etc/letsencrypt/live/example.com/cert.pem -noout -enddate | awk -F'=' '{print $2}' | xargs -I {} date -d {} +%s | awk -v now=$(date +%s) '{print int(($1-now)/86400)}'
当结果小于14天时触发告警。
/etc/letsencrypt目录,防止容器重启后证书丢失--dry-run参数测试续期流程通过上述方法,开发者可在Docker环境中构建高可靠的SSL证书管理体系,既节省成本又降低维护复杂度。实际部署时,建议先在测试环境验证完整流程,再迁移到生产环境。