行业资讯

用 Caddy 替换 Nginx 做自动 HTTPS 证书管理,我把运维工单减少了 80%

发布时间:2026/8/3 16:30:39
用 Caddy 替换 Nginx 做自动 HTTPS 证书管理,我把运维工单减少了 80% 用 Caddy 替换 Nginx 做自动 HTTPS 证书管理我把运维工单减少了 80%说实话我一度以为 Nginx certbot 就是反向代理的标准答案。直到上个月我们运维群里又因为一张证书过期炸锅凌晨 2 点某个子服务的 Let’s Encrypt 证书没续上用户打不开页面值班同事被连环 call 叫醒。排查了 40 分钟最后发现是 certbot 的定时任务写错了路径renew 成功了但 reload Nginx 那一步没执行。这种事故不是第一次。我翻了下工单系统过去半年光是证书相关的工单就有 47 张占运维总工单的 22%。续期失败、新域名漏配、测试环境证书混用、通配符证书申请脚本跑飞……每张工单看起来都不大但加起来能把人烦死。我把 Nginx 换成了 Caddy。三个月后证书类工单从月均 15 张降到 3 张下降了 80%。这篇文章不是吹 Caddy 多先进而是把我迁移过程中踩过的坑、省掉的步骤和真正省下的成本讲清楚。为什么 Nginx certbot 会越来越累我们原来的架构其实不复杂Nginx 做反向代理certbot 负责 ACME 申请和续期crontab 每天跑一次certbot renew nginx -s reload。理论上这套组合能跑但人一多、环境一多问题就开始冒头reload 时机不好把控certbot 续期后必须 reload Nginx否则新证书不生效。crontab 里加nginx -s reload看起来简单但只要某次 reload 时 Nginx 配置文件刚好有语法错误整个代理就挂了。多域名配置重复劳动每新增一个子域名就要改 Nginx server 块、手动跑 certbot、再改一遍证书路径。测试环境还经常复制生产配置结果把正式证书装到 test 域名上。通配符证书难搞Let’s Encrypt 的 DNS-01 挑战要写 provider 脚本不同 DNS 厂商脚本还不一样密钥权限、TTL、ACME 账户共享都是坑。证书状态不透明运维同学想知道某张证书还剩几天只能 ssh 到机器上openssl x509 -in ... -noout -dates或者翻 certbot logs。这些不是 certbot 或 Nginx 的 bug而是两个工具拼在一起必然产生的接缝成本。Caddy 的自动 HTTPS 到底自动在哪里Caddy 的自动 HTTPS 不是简单封装了 certbot而是把证书生命周期完全内嵌到服务器里启动时发现配置里有域名自动向 ACME 申请证书证书快过期时自动续期不需要 crontab续期成功后自动热重载不用手动nginx -s reload默认支持 OCSP Stapling、TLS 1.3、HTTP/2、HTTP/3配置文件语法简单到离谱。核心就一句话你把域名写进 Caddyfile剩下的事 Caddy 自己搞定。我贴一个把我们 80% 场景都覆盖掉的配置{ email opsexample.com auto_https off } api.example.com { reverse_proxy 127.0.0.1:8080 } www.example.com, example.com { reverse_proxy 127.0.0.1:3000 encode gzip zstd header Cache-Control public, max-age3600 } grafana.example.com { reverse_proxy 127.0.0.1:3001 basicauth { admin $2a$14$... } }上面这个 Caddyfile 做了什么三个子域名共用 443 端口自动申请并维护三张 Let’s Encrypt 证书静态资源自动 gzip/zstd 压缩Grafana 加了基础认证不用改应用本身。最关键的是我从头到尾没有写一行 certbot 命令也没有配置 crontab。迁移过程不是把配置翻译一遍而是重新想边界我一开始也犯了一个错误想把 Nginx 的server {}块逐行翻译成 Caddyfile。结果写出来又臭又长还跑不通。Caddy 的设计哲学和 Nginx 不一样。Nginx 是声明式配置 你要手动处理副作用Caddy 是声明意图 它帮你处理副作用。想明白这一点迁移反而简单了。我的迁移分四步第一步梳理现网域名和证书先拿到所有 Nginx server_name 和对应证书# 提取所有 server_namegrep-Rserver_name/etc/nginx/sites-enabled/|awk{print $2}|tr; |tr \n|sort-u# 查看证书到期时间forcrtin/etc/letsencrypt/live/*/*.pem;doecho$crt:$(openssl x509-in$crt-noout-dates|grepnotAfter)done这一步帮我发现两个幽灵域名一个已经下线但证书还在续期一个测试域名用了三个月居然没证书。第二步并行跑 Caddy用 hosts 做灰度我没有直接切流量而是在同一台机器起了一个 Caddy 实例监听8443端口。本地/etc/hosts把某个域名指到127.0.0.1浏览器访问https://域名:8443验证 Caddyfile。# 灰度验证配置 test-api.example.com:8443 { tls internal reverse_proxy 127.0.0.1:8080 }tls internal让 Caddy 自己签发本地证书不用真实 ACME这样可以在不触发 Let’s Encrypt 速率限制的情况下反复测试。第三步双轨并行 DNS 权重切流验证通过后我把 production 的 DNS A 记录权重改成 50/50一半流量走 Nginx一半走 Caddy。跑了 48 小时监控没报警错误率没变化才把所有域名切到 Caddy。第四步下线 Nginx 和 certbot这一步要慢。我先停了 certbot 的 crontab但没卸载。等 Caddy 稳定运行两周、经历过一次证书自动续期后我才把 Nginx 和 certbot 从服务器上清掉。真实踩坑记录迁移不是一帆风顺我记了四条印象最深的坑坑 1默认自动 HTTPS 和内部负载均衡冲突Caddy 默认会尝试把所有域名都申请公网证书。但我们有一批*.svc.local的内网域名Caddy 启动时疯狂报错因为 ACME 验证不到内网地址。解决方式不是关掉 HTTPS而是给内网域名显式指定内部 CA 或自签名internal-api.svc.local { tls internal reverse_proxy 10.0.1.15:8080 }坑 2Caddyfile 里一个逗号空格导致整段不生效Caddyfile 的站点地址用逗号分隔时www.example.com, example.com和www.example.com,example.com效果一样但如果你在逗号后面多打了一个空格再换行某些老版本解析会挂。我养成了每改一次就用caddy validate --config /etc/caddy/Caddyfile检查的习惯。坑 3自动续期日志被隐藏排查麻烦Caddy 默认日志级别是 INFO证书续期成功不会刷屏。但某次我手动清掉了~/.local/share/caddy/certificates目录Caddy 启动时重新申请证书日志里只显示 “obtaining new certificate”没有进度。后来我把日志级别调到 DEBUG才看到 ACME 挑战细节caddy run--config/etc/caddy/Caddyfile--adaptercaddyfile21|tee/var/log/caddy-debug.log坑 4某些老旧客户端不支持默认 TLS 配置Caddy 默认禁用 TLS 1.0/1.1对现代客户端完全没问题。但我们有一台 2016 年的工业设备只支持 TLS 1.0切到 Caddy 后连不上。解决方式是临时放宽这个站点的 TLSlegacy.example.com { tls { protocols tls1.0 tls1.2 } reverse_proxy 127.0.0.1:9000 }这条我单独写进了迁移 checklist避免一刀切的默认配置把老设备干废。效果省下的不只是工单三个月后我拉了一组数据指标迁移前月均迁移后月均变化证书类运维工单15 张3 张-80%新域名上线耗时45 分钟5 分钟-89%证书续期失败告警2.3 次0 次-100%Nginx reload 失败事故1 次/季度0 次-100%工单减少主要是因为三件事不用再麻烦人了新域名开发在 Caddyfile 加两行MR 合并后 CI 自动 reload续期失败Caddy 自己处理失败会重试不再依赖 crontab证书路径错配Caddy 按域名自动匹配证书不存在复制错证书的问题。更意外的是因为 Caddyfile 比 Nginx 配置短很多新人上手成本也低了。原来 Nginx 的 server 块动辄几十行现在平均每个站点 3-5 行。写在最后我不是说 Caddy 在所有场景都比 Nginx 强。如果你需要做复杂的七层负载均衡、动态 upstream、Lua 脚本、或者你已经深度依赖 Nginx 生态那 Nginx 依然是更好的选择。但在我这个场景里——反向代理 多域名 HTTPS 自动证书维护——Caddy 把接缝成本降到了接近零。如果你也被证书续期、新域名配置、reload 失败这些问题折腾过我建议先拿一个低优先级域名做灰度。迁移本身不难难的是你愿意承认原来的组合虽然能跑但已经不适合现在的团队规模。一张证书过期的影响可能只有几分钟但它凌晨 2 点把人叫醒的代价远比那几分钟大得多。