我的学习 我的学习写字 · 记录 · 分享

用 Docker 跑一个博客:为什么选 Caddy 而不是 Nginx

· 约 1 分钟读完 #Docker#建站#HTTPS

用 Docker 跑一个博客:为什么选 Caddy 而不是 Nginx

传统上部署一个 HTTPS 站点,流程是这样的:装 Nginx、装 certbot、写配置、申请证书、配定时任务续期、再写一遍跳转规则。每一步都不难,但每一步都可能出问题——尤其是证书续期,忘了就等 90 天后站点报警。

Caddy 把这一整套收进了一行:

hahaha.asia {
	root * /srv
	file_server
}

就这样。它自己会去找 Let's Encrypt 申请证书,自己续期,自己把 HTTP 请求跳到 HTTPS。

它到底做了什么

概要说一下自动 HTTPS 背后的几个动作:

  • 首次启动时向 ACME 服务端注册账户并申请证书
  • 通过 HTTP-01 或 TLS-ALPN-01 挑战证明域名归属
  • 把证书存进数据卷(默认 /data),重启不会重复申请
  • 到期前 30 天开始自动续期
  • 自动把 HTTP 重定向到 HTTPS,并加上 HSTS 等安全头

这意味着证书必须持久化。在 Docker 里就是别把 /data 放在容器可写层,要挂一个具名卷:

volumes:
  - caddy_data:/data

不挂的后果是:容器每次重建都重新申请一次证书,很快就会撞上 Let's Encrypt 的速率限制(同一个域名一周最多 5 次重复签发)。

国内服务器的两个坑

第一个坑是 Docker Hub 拉不动。国内机器直连 registry-1.docker.io 基本超时,得配镜像加速:

{
  "registry-mirrors": ["https://mirror.ccs.tencentyun.com", "https://docker.m.daocloud.io"]
}

改完执行 systemctl reload docker 生效。腾讯云机器用腾讯自己的镜像源最快。

第二个坑是 80 端口被占用。如果服务器上已经装了面板自带的 Nginx,它默认就占着 80。这时候要么让 Caddy 只监听 443(走 TLS-ALPN 挑战,不依赖 80 端口),要么把前面的 Nginx 让开。

判断依据很简单:ss -tlnp | grep ':80',看是谁在听。

小结

如果只是想安静地放一个静态站点,Caddy 是目前投入产出比最高的选择:配置短、依赖少、证书全自动。

要写自己的配置,建议直接翻 官方文档,比搜来的二手教程准确得多。