用 Caddy 让所有服务自动接入 HTTPS
自托管服务最怕的一关是 HTTPS:证书申请、续期、多域名管理,手工做一两次就烦了。Caddy 的核心卖点就是——写一个配置,证书全自动。本服务器上的六个服务(webui、静态站点、各工具面板)共用一个 Caddy 实例,全部由同一份 Caddyfile 接管。
架构
所有应用容器跑在 Docker 内部网络 maim_bot 上,不直接对外暴露端口。Caddy 容器挂在同一网络,通过容器名反向代理到各服务。只有 Caddy 自己开了 80 和 443 端口到外网。
互联网
|
└─ 80/443 → Caddy (maibot-caddy)
├─ maibot.wuee.cn → maim-bot-core:8001
├─ wuee.cn → 静态文件 /srv
├─ napcat.wuee.cn → maim-bot-napcat:6099
├─ astrbot.wuee.cn → astrbot:6185
├─ gs.wuee.cn → gsuid_core:8765
└─ sqlite.wuee.cn → sqlite-web:8080
Caddyfile
完整配置仅几十行。域名解析到服务器 IP 后,Caddy 会在容器启动时自动从 Let's Encrypt 申请证书。
maibot.wuee.cn {
reverse_proxy maim-bot-core:8001
}
wuee.cn {
root * /srv
file_server
}
napcat.wuee.cn {
rewrite / /webui/
reverse_proxy maim-bot-napcat:6099
}
astrbot.wuee.cn {
reverse_proxy astrbot:6185
}
gs.wuee.cn {
rewrite / /app/
reverse_proxy gsuid_core:8765
}
sqlite.wuee.cn {
reverse_proxy sqlite-web:8080
}
关键配置点
- 容器名即 host 名:同一个 Docker 网络里,容器名就是 DNS 名,不需要写 IP。
- 路径重写:gs.wuee.cn 的 WebUI 实际在
/app/子路径,rewrite / /app/让访问根路径直接进应用,避免浏览器跳转丢失 auth header。 - 证书持久化:Caddy 的证书和配置保存在 Docker 命名卷
caddy_data和caddy_config,容器重建后证书不丢失。 - 静态站点映射:wuee.cn 直接 mount 宿主机
/var/www/wuee.cn到容器/srv,改 HTML 即时生效,零构建。
注意:Let's Encrypt 需要 80 端口可达。如果服务器防火墙或云服务商安全组没放行 80/443,证书申请会失败,Caddy 启动日志会报
acme: error presenting token。Docker Compose 片段
caddy:
image: caddy:2
container_name: maibot-caddy
restart: always
ports:
- "80:80"
- "443:443"
volumes:
- ./Caddyfile:/etc/caddy/Caddyfile:ro
- /var/www/wuee.cn:/srv:ro
- caddy_data:/data
- caddy_config:/config
depends_on:
- core
- napcat
- astrbot
- sqlite-web
networks:
- maim_bot
证书续期是 Caddy 自动完成的,不需要 cron,不需要 certbot。这是它相对 Nginx + Let's Encrypt 最大的省心之处。