DNS 与 HTTPS
BangNiCMS 内置 Caddy 作为反向代理与自动 HTTPS 入口,部署完成后无需任何手动配置即可获得有效证书。本文帮你理解工作机制并排查常见问题。
Caddy 的角色
Section titled “Caddy 的角色”部署后的 6 个容器中,bangnicms-caddy 负责:
浏览器请求 (HTTPS) │ ▼┌──────────────────┐│ bangnicms-caddy │ ← 监听 80 / 443 端口│ (反向代理 + ACME)│└──┬───────────┬───┘ │ │ │ └─── admin.example.com → bangnicms-admin:6534 │ └─── example.com → bangnicms-web:6533Caddy 同时:
- 80 端口:承担 ACME HTTP-01 challenge(证书签发验证),并对其它请求 301 跳转到 HTTPS
- 443 端口:处理 HTTPS 请求,反向代理到对应内部服务
- 自动续期:证书剩余 30 天时自动续签
证书签发原理(Let’s Encrypt + ACME)
Section titled “证书签发原理(Let’s Encrypt + ACME)”Caddy 启动时为 DOMAIN 与 admin.DOMAIN 两个域名同时申请证书:
- 向 Let’s Encrypt 发起 ACME 请求
- Let’s Encrypt 反向访问
http://你的域名/.well-known/acme-challenge/... - Caddy 在该路径返回特定 token 完成验证
- Let’s Encrypt 签发证书(90 天有效)
- 证书存储到
/data/caddy/(容器内 volume,主机映射到bangnicms_caddy_data)
整个过程完全自动,无需手动操作。
验证证书已签发
Section titled “验证证书已签发”curl -I https://你的域名期望响应:
HTTP/2 200server: Caddy打开 https://你的域名,地址栏出现锁图标即成功。
点击锁图标 → 证书 → 应看到:
- Issuer:
Let's Encrypt - Valid until: 约 90 天后
Caddy 日志验证
Section titled “Caddy 日志验证”docker logs bangnicms-caddy --tail 60 | grep -i "obtained\|certificate"期望输出含:
"msg": "obtained certificate""identifiers": ["你的域名", "admin.你的域名"]故障排查清单
Section titled “故障排查清单”故障 1:Caddy 一直卡在 starting / restarting
Section titled “故障 1:Caddy 一直卡在 starting / restarting”docker logs bangnicms-caddy --tail 80症状 A:timeout / connection refused / lookup ... no such host
Section titled “症状 A:timeout / connection refused / lookup ... no such host”原因:DNS 没生效,或 80/443 端口外部无法访问。
排查:
# 1. 在你的本地电脑(不是服务器)上 pingping 你的域名ping admin.你的域名两条都必须返回服务器公网 IP。
# 2. 在你的本地电脑上检测 80 端口curl -v http://你的域名应能拿到 308 跳转到 HTTPS。如果连不上:
- 云厂商安全组:阿里云 / 腾讯云 → 检查 80/443 已放行
- 服务器防火墙:
sudo ufw status,应看到80/tcp ALLOW、443 ALLOW - CDN 干扰:Cloudflare 启用了”代理 (Proxied)“会拦截 ACME,请把 DNS 记录的橙云改为灰云 (DNS only)
症状 B:too many requests / rate limit
Section titled “症状 B:too many requests / rate limit”原因:Let’s Encrypt 速率限制(每域名每周 50 次失败重试)。
解决:等 1 小时后再 Restart caddy 容器。如频繁触发,强烈建议先把 DNS 配对再部署。
症状 C:unauthorized: Invalid response
Section titled “症状 C:unauthorized: Invalid response”原因:80 端口被其他服务占用。
排查:
sudo lsof -i :80如果看到 nginx / apache / 其他进程,先停止它们:
sudo systemctl stop nginxsudo systemctl disable nginx故障 2:浏览器显示”您的连接不是私密连接”
Section titled “故障 2:浏览器显示”您的连接不是私密连接””区分两种情况
Section titled “区分两种情况”- 访问
https://9443端口(Portainer):这是 Portainer 自签证书,正常现象,点”高级 → 继续访问”。详见 Portainer 部署。 - 访问主域名
https://example.com:这是异常,需排查。
异常情况排查
Section titled “异常情况排查”docker logs bangnicms-caddy --tail 60- 看到
obtained certificate→ 证书已成功,可能是浏览器缓存。清除浏览器缓存重试或用无痕窗口。 - 看到错误 → 按上面”故障 1”流程排查。
故障 3:HTTPS 不自动跳转
Section titled “故障 3:HTTPS 不自动跳转”访问 http://example.com 应自动 308 跳转到 https://example.com。
如果没跳转:
docker logs bangnicms-caddy --tail 40通常是 Caddy 还没拿到证书,证书签发完成后会自动启用跳转。
故障 4:admin.example.com 打不开但 example.com 正常
Section titled “故障 4:admin.example.com 打不开但 example.com 正常”原因:DNS 只配了 @ 一条记录,没配 admin 子域名。
解决:到 DNS 控制台补一条 A 记录:
| Type | Name | Content | TTL |
|---|---|---|---|
| A | admin | 服务器 IP | Auto |
等 5-10 分钟生效,再 docker restart bangnicms-caddy 重新签发证书。
证书自动续期
Section titled “证书自动续期”Caddy 自动续期机制:
- 每天检查所有证书的有效期
- 距过期 < 30 天时自动续签
- 续签失败会写日志,但不影响现有证书使用
无需任何手动操作。如果想确认续期是否正常:
docker exec bangnicms-caddy ls -la /data/caddy/certificates/acme-v02.api.letsencrypt.org-directory/你的域名/应能看到 .crt 与 .key 文件,修改时间是最近一次续签时间。
多语言子域名场景
Section titled “多语言子域名场景”如果你在安装向导第 4 步选了 urlStrategy: "subdomain"(多语言走子域名),还需要为每个语言子域名配 DNS:
| Type | Name | Content |
|---|---|---|
| A | @ | 服务器 IP |
| A | admin | 服务器 IP |
| A | en | 服务器 IP(启用 en-US 语言时) |
| A | es | 服务器 IP(启用 es-ES 语言时) |
并需要在 docker-compose.yml 里把 Caddyfile 配置追加这些子域名。这是高级用法,详见 多语言(即将上线)。
国内 ICP 备案与 HTTPS
Section titled “国内 ICP 备案与 HTTPS”如服务器在国内(阿里云/腾讯云国内机房),必须先 ICP 备案才能:
- 用 80 端口 → 影响 Caddy ACME challenge
- 用 443 端口 → 影响 HTTPS
未备案时建议:
- 先用海外服务器开发(香港/新加坡/美国)
- 完成业务上线后再迁移国内(如有需要)
重置 Caddy 证书
Section titled “重置 Caddy 证书”极端情况下需要清空所有证书重来:
docker stop bangnicms-caddydocker volume rm bangnicms_caddy_datadocker start bangnicms-caddyCaddy 会重新申请所有证书。注意:会触发 Let’s Encrypt 速率限制窗口,确认问题后再操作。
证书与 HTTPS 都正常后,进入下一步:
我们会配置品牌(LOGO / 主色 / 副标题)、SEO 默认、上传策略、菜单这 10 件最关键的事,让站点真正”上线”。