静态站点部署本来应该是最省心的环节,但域名、备案、证书三件事凑在一起,还是花了一整天。
一、为什么不用 GitHub Pages
对国内读者来说,github.io 的访问质量不稳定。自定义域名能解决 DNS 层面的问题,但源站仍然在境外,体验依旧取决于链路。
所以选了阿里云 ESA Pages:国内的边缘节点,并且我的域名备案接入商本来就是阿里云——这省掉了「接入备案」这一整个流程。
二、构建配置
仓库根目录放一个 esa.jsonc,它是唯一配置来源,会覆盖控制台设置:
{
"name": "hzlzs",
"installCommand": "npm install",
"buildCommand": "npm run build",
"assets": {
"directory": "./dist",
"notFoundStrategy": "404Page"
}
}notFoundStrategy 选 404Page 而不是 singlePageApplication——静态博客有真正的 404 页面,不该把所有未命中路径都返回 index.html。
三、域名接入的顺序
这里最容易绕晕。正确顺序是:
- 在 ESA 站点管理里添加站点(不是先建 Pages 项目)
- 按提示加一条
_esaauth的 TXT 记录做归属验证 - 站点给一条 CNAME 接入域名,加到云解析
- 等站点状态变成「已启用」
- 最后回到 Pages 项目绑定域名
顺序错了会报 ActiveSiteNotExist,意思是「你绑定的域名还没有对应的已激活站点」。
四、证书这一关
平台自带的免费证书第一次签发时,边缘节点只下发了叶子证书,没有中间证书:
echo | openssl s_client -connect example.com:443 -servername example.com \
2>/dev/null | grep -c "BEGIN CERTIFICATE"
# 1 ← 不完整浏览器因此判定「不安全」——有些浏览器会自己去补拉中间证书,所以会出现「Chrome 正常、Edge 报错」的诡异现象。
解法是换成自定义证书,下载含链版本再上传:
# 期望输出 2 或更多
echo | openssl s_client -connect example.com:443 -servername example.com \
2>/dev/null | grep -c "BEGIN CERTIFICATE"上传后在站点的 HTTPS 配置里选中并启用,等 5-15 分钟边缘同步。
五、几个排查命令
# 看线上实际下发的证书
echo | openssl s_client -connect example.com:443 -servername example.com \
2>/dev/null | openssl x509 -noout -issuer -dates
# 看 DNS 是否生效
dig +short example.com CNAME
# 看 HTTP 响应头
curl -sSI https://example.com | head -20六、最后的清单
- 生产分支要设成仓库实际分支(很多人仓库是
master,平台默认main,结果 push 了不构建) - 私有仓库在仓库列表里默认不显示,要用搜索框搜
- 强制 HTTPS 要在站点配置里开,否则
http://仍然可访问 - 证书到期前记得续期:自定义证书一般 90 天
部署这件事没有技术含量,但每一步的顺序都不能错。把它写下来,下次换平台时能省一天。