将应用部署到 Fly.io 后根域名工作正常,但 www.yoursite.com 抛出 SSL 握手错误?你不是一个人。这个 Error 525 发生是因为 Fly.io 需要为每个主机名单独的 SSL 证书——大多数部署指南完全跳过这一步。
以下是修复方法,已在生产部署中测试和验证。
问题
你已经部署到 Fly.io,添加了自定义域名,一切看起来都很好。然后你尝试访问 www.yoursite.com 并得到:
Error 525: SSL handshake failed与此同时,yoursite.com(没有 www)工作正常。怎么回事?
为什么会发生这种情况
Fly.io 使用 Let's Encrypt 提供 SSL 证书,但这里有个问题:为 example.com 添加证书不会自动覆盖 www.example.com。
它们被视为完全独立的主机名。你需要明确为 www 子域名添加证书。
解决方案(5 步)
步骤 1:安装 Fly.io CLI
如果你还没有,安装 flyctl:
# 安装 flyctl
curl -L https://fly.io/install.sh | sh
# 添加到 PATH
export FLYCTL_INSTALL="$HOME/.fly"
export PATH="$FLYCTL_INSTALL/bin:$PATH"
# 使其永久生效(添加到 ~/.bashrc 或 ~/.zshrc)
echo 'export FLYCTL_INSTALL="$HOME/.fly"' >> ~/.bashrc
echo 'export PATH="$FLYCTL_INSTALL/bin:$PATH"' >> ~/.bashrc
source ~/.bashrc
# 验证是否工作
flyctl version步骤 2:检查你当前的证书
首先,查看你已有的证书:
flyctl certs list -a YOUR_APP_NAME你可能会看到类似这样的内容:
Host Name Added Status
example.com 1 month ago Ready
api.example.com 1 month ago Ready注意到缺少什么了吗?www 子域名。
步骤 3:添加 www 证书(这解决了问题)
这是解决问题的关键命令:
flyctl certs add www.example.com -a YOUR_APP_NAMEFly.io 将自动为你的 www 子域名提供 Let's Encrypt SSL 证书。你会看到类似这样的输出:
You are creating a certificate for www.example.com
We are using Let's Encrypt for this certificate.
Your certificate for www.example.com is being issued.
You can validate your ownership of www.example.com by:
1: Adding an AAAA record to your DNS service which reads:
AAAA @ 2a09:8280:1::X:XXXX不用担心 DNS 验证——如果你的根域名已经在工作,www 子域名将自动验证。
步骤 4:验证证书已准备好
等待 1-2 分钟,然后检查证书状态:
flyctl certs show www.example.com -a YOUR_APP_NAME查找 "Status: Ready"。如果它显示"Awaiting certificates",再等一分钟然后再次检查。
一旦准备好,你的证书列表应该显示:
flyctl certs list -a YOUR_APP_NAMEHost Name Added Status
example.com 1 month ago Ready
www.example.com 13 seconds ago Ready完美。
步骤 5:配置 Cloudflare SSL/TLS 模式
如果你使用 Cloudflare 进行 DNS(你应该这样做),这一步至关重要。
- 登录你的 Cloudflare 仪表板
- 选择你的域名
- 前往 SSL/TLS → 概述
- 将加密模式设置为 "完全"(不是"灵活"或"完全(严格)")
为什么选择"完全"?
- 灵活:Cloudflare 对访客使用 HTTPS,但对 Fly.io 使用 HTTP(不安全,会导致问题)
- 完全:Cloudflare 对访客和 Fly.io 都使用 HTTPS(正确)
- 完全(严格):需要受信任的证书颁发机构,但 Fly.io 管理自己的证书(会导致错误)
配置你的 DNS 记录(Cloudflare)
确保你的 DNS 记录设置正确:
根域名 (example.com):
- 类型:
A或AAAA - 名称:
@(或留空) - 内容:你的 Fly.io IP 地址(来自
flyctl ips list) - 代理状态:已代理(橙色云启用)
www 子域名 (www.example.com):
- 类型:
CNAME - 名称:
www - 目标:
example.com(指向根域名) - 代理状态:已代理(橙色云启用)
橙色云(已代理)很重要——它通过 Cloudflare 的 CDN 路由流量并启用 SSL。
测试一切
验证两个域名都工作:
# 测试根域名
curl -I https://example.com
# 测试 www 子域名
curl -I https://www.example.com两者都应该返回 HTTP/2 200(或 HTTP/1.1 200)。如果你遇到错误,请参阅下面的故障排除部分。
常见错误和修复
Error 525:SSL 握手失败
症状:www 子域名抛出 Error 525,根域名工作正常
原因:
- Fly.io 上缺少 www 证书
- Cloudflare SSL/TLS 模式设置为"灵活"或"完全(严格)"
修复:
# 添加 www 证书
flyctl certs add www.example.com -a YOUR_APP_NAME
# 等待 2 分钟让证书颁发
sleep 120
# 验证是否准备好
flyctl certs show www.example.com -a YOUR_APP_NAME还要验证 Cloudflare SSL/TLS 模式设置为 "完全"。
www 子域名返回连接超时
症状:www 子域名根本不加载,没有错误页面
原因:
- DNS CNAME 记录缺失或不正确
- DNS 未通过 Cloudflare 代理
- DNS 传播未完成
修复:
- 检查 Cloudflare DNS 设置中的 www CNAME 记录
- 确保橙色云(已代理)已启用
- 等待 5-15 分钟让 DNS 传播
- 清除浏览器缓存或在隐身模式下测试
证书显示"Awaiting Certificates"超过 5 分钟
症状:flyctl certs show 一直显示"Awaiting certificates"
原因:
- DNS 记录未正确指向 Fly.io
- Cloudflare 代理干扰证书验证
修复:
# 验证你的 DNS 记录正确
dig www.example.com
# 检查 DNS 是否解析到 Fly.io
nslookup www.example.com
# 如果卡住,删除并重新添加证书
flyctl certs delete www.example.com -a YOUR_APP_NAME
flyctl certs add www.example.com -a YOUR_APP_NAME为什么单独的证书很重要
在传统的共享托管中,通配符 SSL 证书(*.example.com)覆盖所有子域名。但 Fly.io 通过 Let's Encrypt 单独提供证书。
这给你更多控制,但需要为每个子域名明确设置:
example.com→ 需要自己的证书www.example.com→ 需要自己的证书api.example.com→ 需要自己的证书blog.example.com→ 需要自己的证书
你明白了。
Fly.io + Cloudflare 最佳实践
- 在上线前为所有计划使用的子域名添加证书
- 为 Fly.io 部署使用 Cloudflare 的"完全"SSL/TLS 模式
- 启用 Cloudflare 代理(橙色云)以获得 CDN 和 DDoS 保护
- 在宣布你的网站之前测试 www 和非 www 版本
- 如果你想强制使用一个版本而不是另一个,在你的应用中设置重定向
故障排除的有用命令
# 列出你应用的所有证书
flyctl certs list -a YOUR_APP_NAME
# 查看特定证书的详细信息
flyctl certs show www.example.com -a YOUR_APP_NAME
# 删除证书(如果你需要重新开始)
flyctl certs delete www.example.com -a YOUR_APP_NAME
# 检查你应用的 IP 地址
flyctl ips list -a YOUR_APP_NAME
# 检查 DNS 解析
dig example.com
dig www.example.com
# 使用详细输出测试 SSL 连接
curl -vI https://www.example.com
# 检查应用状态
flyctl status -a YOUR_APP_NAME
# 查看应用日志(用于调试)
flyctl logs -a YOUR_APP_NAME为什么大多数指南跳过这个
大多数 Fly.io 部署教程专注于让你的应用运行并添加单个自定义域名。他们假设你只会使用 example.com 或 www.example.com——不是两者都用。
但实际上,用户会输入两个版本。搜索引擎会索引两者。你不希望一半的流量遇到 SSL 错误。
添加 www 证书需要 30 秒,但可以节省数小时的后续调试时间。
替代方案:将 www 重定向到非 www(或反之)
如果你不想维护两个版本,你可以在应用中设置重定向。
选项 1:将 www 重定向到非 www
大多数框架都有中间件来实现这个。例如,在 Express.js 中:
app.use((req, res, next) => {
if (req.hostname.startsWith('www.')) {
return res.redirect(301, `https://${req.hostname.slice(4)}${req.url}`)
}
next()
})选项 2:将非 www 重定向到 www
app.use((req, res, next) => {
if (!req.hostname.startsWith('www.')) {
return res.redirect(301, `https://www.${req.hostname}${req.url}`)
}
next()
})但即使你重定向,你仍然需要两个证书,否则重定向不会工作(用户会在你的应用可以重定向他们之前遇到 SSL 错误)。
结论
Fly.io www 子域名 SSL 问题是那些即使是有经验的开发者也会遇到的"坑"之一。一旦你知道修复方法就很简单:
- 为 www 添加单独的证书:
flyctl certs add www.example.com -a YOUR_APP_NAME - 将 Cloudflare SSL/TLS 设置为"完全"模式
- 等待 1-2 分钟让证书准备好
- 测试两个域名
就这样。没有复杂的配置,没有服务器重启,没有编辑配置文件。只是一个大多数部署指南忘记提到的命令。
现在你的用户可以使用或不使用 www 访问你的网站,两者都能正常工作。
相关指南:
资源:
Fred
AUTHORFull-stack developer with 10+ years building production applications. I've been deploying to Cloudflare's edge network since Workers launched in 2017.
Need a developer who gets it?
POC builds, vibe-coded fixes, and real engineering. Let's talk.
Hire Me →
