域名与 SSL
sh0 使用 Caddy 作为反向代理,这意味着每个域名通过 Let's Encrypt 自动获得 HTTPS。无需手动管理证书,无需 cron 任务,无需配置文件——开箱即用。
域名如何工作
当您为应用分配域名时,sh0 自动配置 Caddy 以:
- 监听该域名的传入请求(端口 80 和 443)。
- 从 Let's Encrypt 获取并安装 SSL 证书。
- 将所有 HTTP 流量重定向到 HTTPS。
- 将 HTTPS 流量反向代理到正确的 Docker 容器。
- 在证书过期前自动续期。
整个过程是自动的。一旦您添加域名并将其 DNS 指向您的服务器,其他一切都是自动的。
默认子域名
在 sh0 Cloud 上部署的每个应用都会获得一个 *.sh0.app 下的免费子域名。这对以下用途很有帮助:
- 无需配置 DNS 的快速测试
- 预发布环境
- Pull Request 的预览部署
子域名基于您的应用名称:如果您的应用名为 my-api,它将可在 my-api.sh0.app 访问。
关闭 *.sh0.app
sh0 启动时会向 sh0 云代理(proxy.sh0.app)注册其标识、公网 IP 地址和版本,以获取 *.sh0.app 地址。若不希望服务器接入该代理,请在 sh0 服务首次启动前,在其环境中设置 SH0_CLOUD_REGISTRATION=off。
在新服务器上,安装脚本会替您完成:
curl -fsSL https://get.sh0.dev | bash -s -- --no-cloud在已安装的服务器上,添加一个 systemd drop-in 并重启 sh0:
mkdir -p /etc/systemd/system/sh0.service.d
printf '[Service]\nEnvironment=SH0_CLOUD_REGISTRATION=off\n' \
> /etc/systemd/system/sh0.service.d/cloud-registration.conf
systemctl daemon-reload && systemctl restart sh0然后运行 sh0 doctor:云注册一行应显示“disabled”。可接受的值为 off、0、false 和 no。
添加自定义域名
要为您的应用添加自定义域名:
- 导航到您的应用并打开 Domains 标签。
- 点击 Add Domain。
- 输入您的域名(例如
app.example.com或example.com)。 - 保存并配置您的 DNS(见下文)。
您可以为单个应用添加多个域名。所有域名将服务于同一个应用。这对以下场景很有用:
- 同时提供
example.com和www.example.com - 支持指向同一服务的多个域名
- 在自定义域名旁保留默认子域名作为备用
DNS 配置
通过在注册商或 DNS 提供商处添加 DNS 记录,将域名指向您的 sh0 服务器:
| 类型 | 名称 | 值 | 用途 |
|---|---|---|---|
| A | @ | 您的服务器 IP | 根域名 (example.com) |
| A | app | 您的服务器 IP | 子域名 (app.example.com) |
| CNAME | www | example.com | www 重定向 |
# For app.example.com
Type: A
Name: app
Value: 203.0.113.50
TTL: 300
# For example.com (root domain)
Type: A
Name: @
Value: 203.0.113.50
TTL: 300dig app.example.com 或 nslookup app.example.com 验证 DNS 配置是否正确。自动 SSL
SSL 证书完全由 Caddy 管理。无需配置,无需上传证书,无需维护续期脚本。
Let's Encrypt 如何工作
当您添加域名时,以下自动发生:
- 验证 -- Caddy 发起 ACME HTTP-01 验证以证明域名所有权。
- 签发 -- Let's Encrypt 验证通过并签发证书(通常几秒内完成)。
- 安装 -- Caddy 安装证书并开始提供 HTTPS 流量。
- 续期 -- Caddy 在过期前 30 天自动续期证书。
ufw allow 80/tcp(或等效命令)。通配符域名
通配符域名(例如 *.example.com)允许任何子域名路由到您的应用。这对以下场景很有用:
- 每个租户获得一个子域名的多租户应用
- 每个分支拥有唯一子域名的预览部署
- 基于地理位置或语言的路由
# In sh0 Settings > SSL, configure your DNS provider
# Example for Cloudflare:
DNS_PROVIDER=cloudflare
CLOUDFLARE_API_TOKEN=your-api-tokenSSL 证书状态
每个应用的域名部分显示每个已配置域名的 SSL 状态:
| 状态 | 含义 |
|---|---|
| 活跃 | 证书有效,正在提供 HTTPS 流量。 |
| 等待中 | 尚无证书。自 v1.6.25 起证书按需签发:在该域名的第一次 TLS 握手时才申请证书,因此在有人真正连接之前,域名会一直处于“等待中”。将鼠标悬停在徽标上即可查看仍在等待的原因。 |
| 续期中 | 证书正在续期(过期前 30 天)。 |
| 失败 | 证书配置失败。请检查 DNS 和防火墙设置。 |
自 v1.6.25 起新增两条规则。已激活的域名若其证书从磁盘上消失,会在连续两次检查后回到等待中,绝不会因单次读取而降级。此外,证书到期日期现在直接从证书本身读取,到期告警终于有了可用的值。
故障排除
如果您的域名无法工作或 SSL 证书配置失败,请检查以下常见问题:
DNS 未指向您的服务器
运行 dig +short your-domain.com 并验证其返回您服务器的 IP 地址。如果不是,请更新 DNS 记录并等待传播。
端口 80 被阻止
Let's Encrypt 需要端口 80 来验证域名所有权。确保防火墙允许端口 80 的入站 TCP 流量。使用 sudo ufw status 检查。
其他服务正在使用端口 80/443
如果 Nginx、Apache 或其他 Web 服务器正在运行,可能与 Caddy 冲突。停止其他服务:sudo systemctl stop nginx。
超出速率限制
Let's Encrypt 有速率限制(每周每域名 50 个证书)。如果达到限制,请等待或使用暂存环境进行测试。Caddy 日志会指示速率限制错误。
# Check if DNS resolves correctly
dig +short app.example.com
# Test if port 80 is accessible from outside
curl -I http://app.example.com
# Check Caddy logs for certificate errors
journalctl -u sh0 | grep -i "certificate\|tls\|acme"