Certbot 容器每天重复申请证书:只导出 PEM,没有保留续期状态
临时 Certbot 容器只导出证书文件,下一次任务却丢失续期状态。保留完整配置、复用 renew,并分别检查验证、部署和服务证书。
定时任务每次启动一个临时 Certbot 容器,签发证书后把 PEM 文件上传到 Web 服务器,再删除容器。下一次运行时,/etc/letsencrypt 又是空目录,脚本继续执行 certbot certonly。这种安排可能让例行检查变成反复签发,甚至触发 CA 的申请限制。
这篇针对 Docker 中运行 Certbot、容器之间没有保留完整配置的场景。要让 renew 判断哪些证书需要续期,应保留 Certbot 的本地管理状态,再让每次任务使用同一份状态。只留下 Web 服务器正在使用的证书文件,不能替代续期配置和账户资料。
先看下一次容器究竟能读到什么
检查定时任务的镜像、启动参数和挂载,确认每次运行看到的是同一套 /etc/letsencrypt。注意区分“上传到其他机器的证书副本”和“Certbot 下一次运行使用的配置目录”。
在实际任务所用的容器与挂载环境中,可用 certbot certificates 查看它管理的证书。如果 Web 服务有有效证书,但 Certbot 列表为空,且容器里的配置目录每次都是新建的,就应先修复状态保存。若证书列表和对应续期配置都存在,继续检查任务是否用了另一套配置目录、证书名称或强制签发参数,不能仅凭重复签发就判定容器丢了文件。
已有状态包括账户信息、私钥、证书版本及续期配置。不要只保存 live 下供服务读取的文件,也不要通过一个“询问 CA 是否到期”的参数来替代这些资料。CA 的签发记录无法说明你目前部署的是哪一张证书、服务是否已加载它,也无法替你恢复丢失的私钥。
持久化应先迁移旧状态,再切换挂载
在清理临时容器前,保存仍然可用的 Certbot 状态,并核对它与当前服务部署的证书是否一致。资料含私钥和账户凭据,备份及持久目录只能由需要使用它的账户访问。
以下是 Compose 挂载片段示例,路径需要替换;镜像和验证方式沿用原部署:
volumes:
- /srv/certbot/config:/etc/letsencrypt
- /srv/certbot/work:/var/lib/letsencrypt
/srv/certbot/config 应在切换前装入确认过的完整状态,不能先挂一个空目录再认为旧容器里的配置会自动复制出来。工作目录也按实际 Certbot 运行方式持久保存。使用命名卷同样需要明确迁移、备份及任务如何引用该卷。
避免两个定时任务同时写同一套状态。迁移期间暂停旧任务,保留旧容器或离线备份,确认新任务能列出原证书后再恢复调度。若状态已丢失,只剩服务侧证书,先寻找有效备份;没有备份时需要重新建立受控签发与续期流程,不要靠缩短 cron 间隔尝试恢复。
定时运行 renew,部署动作单独确认
挂载和状态一致后,定时任务通常运行 certbot renew,由它检查已管理证书是否需要续期,并复用保存的验证插件和选项。不要在每次检查中附加 --force-renewal,也不要用重新创建证书名称来掩盖状态问题。
还要确认保存的验证方式在容器内仍可工作。webroot 挑战文件必须能被公网 Web 入口读取;DNS 插件需要相应凭据。手动验证如果没有合适的自动化 hooks,不能仅因为改成 renew 就变成无人值守续期。Docker 里的 Certbot 也不会自动管理另一台机器上的 Nginx。
renew 返回 0,可能只是目前没有证书需要续期。需要在成功续期后上传文件或重新加载服务时,应使用适合部署方式的 deploy hook,并明确它在 Certbot 容器中执行。它不会因此获得远程服务器的路径和权限;上传、部署及服务加载仍需受控的传递流程。
pre/post hooks 用于续期尝试前后的安排,不能当作“本次已经签发新证书”的通知。不要用它们无条件覆盖远端证书,也别把远端加载失败误记为 HTTPS 已更新。
状态、验证、服务证书分别验收
重建 Certbot 容器后,应仍能看到原证书名称及对应续期设置。随后按既有插件做续期模拟,先核对 hooks 是否会停服或修改文件;模拟成功只说明验证流程可用,不代表已经换了生产证书。
真实续期成功时,还应检查证书部署记录及公网服务实际提供的有效期和证书内容。上传成功但服务没有加载新文件,仍然需要处理部署步骤。
Let’s Encrypt 当前支持 ARI 的续期与其他申请路径有不同的频率限制规则,不能把某个旧版本的固定次数当成所有续期的统一额度。已经收到限制响应时,保留具体错误和重试时间,停止重复生产申请;修好持久状态并不会立刻清除已触发的限制。
切换失败时恢复原任务参数、挂载和保存的状态,继续使用仍有效的服务证书。不要删除持久卷来“重新初始化”,也不要清理尚未确认用途的私钥和证书版本。


