acme.sh + 阿里云 DNS-01:泛域名证书自动续期与 CDN 推送
云原生与交付30 阅读约 4 分钟
HTTPS 证书 90 天到期,手动续是个迟早会忘的事。我的目标是「签一次、之后永不操心」。实现它的组合是 acme.sh + 阿里云 DNS-01 + 一张泛域名证书。
为什么用 DNS-01 + 泛域名
证书验证有两种方式:
- HTTP-01:往网站某路径放个文件让 CA 来访问。简单,但签不了泛域名,每个子域都得单独签。
- DNS-01:往 DNS 加一条 TXT 记录证明你拥有域名。能签
*.example.com泛域名,一张证书覆盖所有子域。
我有 jiawen.live、api.、admin.、static. 好几个子域,泛域名证书一张全包,所以选 DNS-01。验证靠调用阿里云 DNS 的 API 自动加删 TXT 记录,全自动无需人工。
daemon 模式:内置 cron 自动续期
acme 用一个独立容器,daemon 模式跑:
acme:
build: ./acme
command: daemon
environment:
ACME_EMAIL: ${ACME_EMAIL}
BASE_DOMAIN: ${BASE_DOMAIN} # 签 BASE_DOMAIN + *.BASE_DOMAIN
Ali_Key: ${ALI_KEY} # acme.sh dns_ali 插件约定的变量名
Ali_Secret: ${ALI_SECRET}
STATIC_DOMAIN: ${STATIC_DOMAIN}
volumes:
- acme-data:/acme.sh # 账户/续期状态持久化,删容器不丢
- ./nginx/certs:/certs # 证书安装目录,网关只读挂同一目录
daemon 模式自带 cron:每天检查、到期前 30 天自动续期。续期后做两件事:把新证书重装到网关证书目录、推送到 CDN 加速域名。整条链路无人值守。
注意 acme-data 卷——它存 acme.sh 的账户和续期配置,必须持久化,否则重建容器就丢了续期状态、得重新签。
续期后自动推 CDN
静态资源走 CDN(加速域名),CDN 也要装证书。传统做法是续期后手动去控制台传新证书——又是个会忘的事。acme.sh 支持「部署钩子」,续期成功自动把证书推到阿里云 CDN:
# deploy-cdn.sh(续期成功后由 acme 自动调用,也可手动触发)
acme.sh --deploy -d "$BASE_DOMAIN" --deploy-hook ali_cdn
于是「网关证书」和「CDN 证书」一起更新,彻底告别手动上传。
冷启动的「鸡生蛋」问题
这套流程有个启动悖论:nginx 配了 443 + ssl,但首次部署时还没有证书,nginx 起不来;可证书又要等服务起来后才能签。 死锁。
解法是先放一张自签占位证书让 nginx 能启动,再签真证书替换:
make cert-selfsigned # 生成自签占位证书,解开「无证书 → 443 起不来」的死锁
make prod # 起完整生产栈(此时用占位证书)
make cert-issue # DNS-01 签发真证书
make prod-reload # 平滑 reload,加载真证书
之后就交给 daemon 自动续期,网关每 6 小时自动 reload 让新证书生效,人不用再碰。
小结
「签一次、永不操心」的 HTTPS 自动化:DNS-01 验证签一张泛域名证书覆盖所有子域,acme daemon 内置 cron 到期前自动续,续期后自动重装网关 + 推送 CDN。记得持久化 acme 数据卷、用自签占位证书解开冷启动死锁。配好之后,证书这件事就从你的待办清单里永久消失了。
相关文章
评论 (7)
小项目生产用 compose 还是直接上 k8s?感觉 k8s 太重了
Mr.Lin
刚好工作里要用,太及时了
Havoc
哈哈我也是这么理解的
zoe
镜像分层讲得透彻
Mr.Lin
马克一下
demo_user
请问多个 server_name 复用同一张证书会有坑吗?
林深时见鹿
HTTP/3 折腾好久,证书这块尤其坑





