部署
本页讲解博客的发布与部署:静态产物如何托管、Vercel 生产部署与测试域流程、Docker 构建四模式,以及"改代码 vs 改内容"的发布选择。部署链路依赖 Git 子模块(themes/matery/ 等),提交时需双仓库一起提交(见第 6 节)。
阅读方式:每个部署目标都按「效果(哪个域名/仓库被更新)→ 对应命令/配置 → 输出」成对给出;配置类小节仍按「如何启用 → 常用选项 → 全部可调项 → 边界与冲突」展开。
1. 静态产物部署(任意静态托管)
用途:Hexo 生成的是纯静态文件,
public/目录可以丢到任何静态托管(Nginx、GitHub Pages、Cloudflare Pages、OSS 等)直接上线。学习路径:如何启用 → 常用选项 → 全部可调项 → 边界与冲突
1.1 如何启用
效果:public/ 里出现完整站点(index.html + 各页面目录 + 静态资源),把它同步到任意 Web 服务器根目录,访问该域名就是你的博客。
对应命令:
npm run build # hexo generate + pagefind 索引,产物在 public/
npm run clean # hexo clean,清 public/ 与缓存输出:public/index.html、public/posts/、public/pagefind/ 等生成完毕;npm run build 退出码 0 即构建成功。
1.2 常用选项
① 部署即同步 public/
效果:拷到 Web 服务器根目录即可上线;域名指向哪里由托管平台决定(本项目生产走 Vercel,见 §2)。
对应命令(示例,按托管方式替换占位符):
rsync -a --delete public/ {{USER}}@{{HOST}}:{{WEB_ROOT}}/输出:服务器目录与本地 public/ 一致,刷新域名看到新页面。
② 根 URL 必须一致
效果:url 正确时 canonical、sitemap、RSS 里的绝对链接都指向你的域名;写错则这些链接仍指向旧域名(SEO 与分享卡片跟着错)。
对应配置(根 _config.yml):
url: https://blog.17lai.site输出:public/sitemap.xml、public/atom.xml 中的 <loc>/<link> 使用该域名。
1.3 全部可调项
| 项 | 类型 | 默认 | 可选值/范围 | 作用 |
|---|---|---|---|---|
url | string | — | 站点完整 URL | canonical/sitemap/RSS 的绝对链接基准 |
public/ | 目录 | — | 任意静态托管根目录 | 部署产物 |
npm run build | 命令 | — | — | hexo generate + pagefind 索引 |
npm run clean | 命令 | — | — | 清 public/ 与 Hexo 缓存 |
1.4 边界与冲突
- 部署即同步
public/:拷到 Web 服务器根目录即可;域名指向哪里由托管平台决定。 - 根 URL 必须一致:
_config.yml的url决定 canonical/sitemap/RSS 里的绝对链接,换托管域名要同步改(见「全局配置」篇)。 - 本项目生产用的是 Vercel(见下节),GitHub Pages 旧部署已停用。
1.5 小结
- 最小可用:
npm run build后同步public/ - 换域名:先改
_config.yml的url,再构建 - 只想本地看:
npx hexo server -p 4100
2. Vercel 生产部署(blog.17lai.site)
用途:生产环境
https://blog.17lai.site。Vercel 关联 GitHub 仓库github.com:appotry/hexo.git(main 分支),push 后自动同步构建,无需手动触发。学习路径:如何启用 → 常用选项 → 全部可调项 → 边界与冲突
2.1 如何启用
效果:hexo.git 的 main 分支多一个提交 + 一个 git tag;几分钟后 https://blog.17lai.site 变成新版本,HTML 里的版本号 ?v= 递增(浏览器/PWA 因此拉新资源)。
对应命令:
# 推送到 hexo.git(生产仓库)
tools/cicd.sh -r "特性说明" # 构建 + 版本递增 + git tag + push输出:
tools/.VERSION递增,并创建对应 git tag- 只推
hexo.git(生产),hexoback.git不动 - Vercel 云端执行
npm run build,产物直接上 CDN
2.2 常用选项
① 发布后验证生产
效果:逐层检查生产域名——构建产物完整、20 个 layout 页面 HTTP 200、评论区存在、版本号三处一致、SW 冒烟等;任一层失败即报错退出。
对应命令:
tools/tests/release-test.sh输出:L1–L14 各层 PASS/FAIL 报告,最后给出总计;全绿才算发布完成。
② 不额外建部署仓库
效果:生产只认 hexo.git,Vercel 只监听它;另建仓库会导致两份产物、域名指向混乱。
对应配置:Vercel 项目的 Git 集成(在 Vercel 控制台,非仓库内配置)。
2.3 全部可调项
| 部署目标 | 触发方式 | 仓库 | 结果域名 |
|---|---|---|---|
| 生产 | tools/cicd.sh -r "特性" | hexo.git(main) | https://blog.17lai.site |
| 测试域 | tools/cicd.sh -t "说明" | hexoback.git | https://blog2.17lai.site |
| 仅内容 | tools/cicd.sh -c "说明" | hexo.git + hexoback.git | 两个域名都更新 |
| 本地调试 | tools/cicd.sh -d | 不推送 | 仅本地预览 |
2.4 边界与冲突
- 构建在 Vercel 云端执行(
npm run build),产物直接上 CDN;本地构建成功不代表云端成功,仍以 Vercel 构建日志为准。 - 不要在生产仓库外另建部署仓库;测试用独立的
hexoback.git(下节)。 - 发布后按发版铁律跑
tools/tests/release-test.sh验证生产环境(20 页面 + 评论区 + 版本一致性)。
2.5 小结
- 最小可用:
tools/cicd.sh -r "说明" - 发版必验:
tools/tests/release-test.sh - 生产改坏:用上一个 git tag 回退后重新
-r - 只有内容:用
-c,不递增版本
3. 测试域流程(hexoback → blog2.17lai.site)
用途:正式发布前先在测试域验证,避免坏改动直接上生产。Vercel 上有第二个项目监听
hexoback.git(测试仓库),部署到https://blog2.17lai.site。学习路径:如何启用 → 常用选项 → 全部可调项 → 边界与冲突
3.1 如何启用
效果:hexoback.git 更新 → https://blog2.17lai.site 变成新版本;生产 blog.17lai.site 完全不变。
对应命令:
# 推测试仓库(Vercel 自动部署到测试域)
tools/cicd.sh -t "说明" # 推测试仓库(Vercel 部署测试域)
# 在测试域跑 PWA 冒烟 + 交互验证
make test-pwa # 7 页 SW 冒烟 + 交互验证输出:-t 只切到 hexoback 部署目标并推送;make test-pwa 输出 7 个页面的 SW 冒烟结果与交互检查结论。
3.2 常用选项
① 测试通过后才推生产
效果:生产域名更新为与测试域相同的产物,并带上递增后的版本号。
对应命令:
tools/cicd.sh -r "特性" # 正式发布(递增版本号 + CDN + git tag)
tools/tests/release-test.sh # 【发版铁律】全量 layout 自动化测试输出:hexo.git 新增提交与 tag;release-test.sh 打印 L1–L14 结果。
② 小改动跳过测试域
效果:仅内容变化时直接双推(生产 + 测试),省一轮等待。
对应命令:
tools/cicd.sh -c "说明"输出:hexo.git 与 hexoback.git 都更新,版本号不变。
3.3 全部可调项
| 仓库 | 监听方 | 命令 | 结果 |
|---|---|---|---|
hexo.git | Vercel 生产项目 | -r / -c | blog.17lai.site |
hexoback.git | Vercel 测试项目 | -t / -c | blog2.17lai.site |
3.4 边界与冲突
- 两仓库完全分开,测试不污染生产;但
-t复用旧版本号,不会产生新 tag。 make test-pwa打的是测试域(blog2.17lai.site),不是本地 4000 端口。- 小改动(仅内容)可跳过测试域直接
-c推送。
3.5 小结
- 最小可用:
-t→make test-pwa - 通过后:
-r→release-test.sh - 只改文章:
-c - 测试域报错:修完重新
-t,不要直接上生产
4. Docker 构建(tools/cicd.sh 四模式)
用途:
tools/cicd.sh是完整的 CI/CD 入口(代理 → 版本管理 → 子仓库同步 → 配置注入 → 构建 → PWA 版本 → 部署推送),支持四种模式。学习路径:如何启用 → 常用选项 → 全部可调项 → 边界与冲突
4.1 如何启用
效果:容器内跑 -d 后,localhost:4000 显示的是真实文章 + 未压缩 + 无 CDN 的调试版本;配置注入与 PWA 生成照常执行,但不推送任何仓库。
对应命令:
docker compose -f docker-compose.test.yml up -d
docker compose -f docker-compose.test.yml exec hexo bash
# 容器内:tools/cicd.sh -d (本地调试构建)
exit
docker compose -f docker-compose.test.yml down输出:public/index.html 重新生成且体积 > 1000 字节;PM2 重启后 4000 端口返回 200。
4.2 常用选项
① 四种模式(原有对照表)
| 参数 | 用途 | 版本处理 | 压缩 | CDN |
|---|---|---|---|---|
-d / --debug | 本地调试 | 不递增 | 关闭 | 清空 |
-c "说明" / --continue | 持续集成(仅更新文章) | 使用旧版本 | 开启 | 置空 |
-r "特性" / --release | 正式发布 | 递增 + git tag | 开启 | jsdelivr |
-t / --test | 本地编译测试 | 使用旧版本 | 开启 | 置空 |
② 各模式的可观察结果
效果:一眼看出跑完命令后"哪个域名/仓库变了、产物长什么样"。
对应模式:下表即四种模式的输出差异。
| 模式 | 推送目标 | 域名变化 | 产物特征 |
|---|---|---|---|
-d / --debug | 不推送 | 无(本地 4000) | 不压缩、CDN 占位符清空、调试可读 |
-c "说明" | hexo.git + hexoback.git | 生产 + 测试都更新 | 压缩、无 CDN、版本号不变 |
-r "特性" | hexo.git | 仅生产更新 | 压缩 + jsDelivr CDN + 新 tag |
-t / --test | hexoback.git | 仅测试域更新 | 压缩、无 CDN、版本号不变 |
③ 本机直接构建
效果:不开 Docker 也能得到同样的产物(配置注入 + pagefind),用于快速验证。
对应命令:
tools/test.sh build # 代理到 tools/hexo-build.sh
npx hexo server -p 4100 # 本地预览,避开 Docker 的 4000输出:public/ 生成;4100 端口可访问,4000 端口不受影响。
4.3 全部可调项
| 项 | 取值 | 作用 |
|---|---|---|
-d / --debug | 无 | 本地调试,不推送 |
-c / --continue | 说明字符串 | 双推,版本号不变 |
-r / --release | 特性字符串 | 单推生产,递增版本 + tag |
-t / --test | 说明字符串 | 单推测试域 |
tools/debugBlog.sh true\|false | 布尔 | 切换调试文章集(独立于 cicd.sh) |
4.4 边界与冲突
- Docker 容器内的 hexo server 端口映射为宿主机 4000 → 容器 4000;本机生成预览用
tools/test.sh server或npx hexo server -p 4100,两者互不冲突。 - 文章集替换已从
cicd.sh移出(2026-09-23):需用少量调试文章加速时,先tools/debugBlog.sh true,再跑tools/cicd.sh -d;调试完tools/debugBlog.sh false还原。构建脚本不应改源文件。 -d不推送,但会改写themes/matery/_config.yml(配置注入产物);这是预期行为,不要把它当成脏改动提交。
4.5 小结
- 最小可用:
tools/cicd.sh -d+ 打开 4000 - 要推送:
-c(双推)/-t(测试)/-r(生产) - 端口冲突:本机预览换 4100
- 加速构建:
debugBlog.sh true是独立步骤
5. 发布流程选择(改代码 vs 改内容)
用途:选错模式会导致"改了但线上没变"(缓存命中旧版本)或"没必要的版本递增"。
学习路径:如何启用 → 常用选项 → 全部可调项 → 边界与冲突
5.1 如何启用
效果:git status --short 有 themes/matery/ 输出 → 代码改动 → 必须 -r;只有 source/ 输出 → 内容改动 → -c/-d 即可。
对应命令:
git status --short themes/matery/ # 有改动 → 代码改动 → -r
git status --short source/ # 仅内容改动 → -d / -c输出:列出被改动文件;空输出表示该目录无改动。
5.2 常用选项
核心原则:改代码用 -r,改内容用 -c/-d。
| 改动类型 | 使用命令 | 原因 |
|---|---|---|
JS/CSS/主题代码(themes/matery/ 下) | tools/cicd.sh -r "特性" | 需递增版本号 + git tag,浏览器/PWA 才拉新版(版本号不变会命中缓存) |
仅文章/内容(source/_posts/ 等) | -d(本地预览)或 -c "说明"(推送) | 内容更新无需版本号,增量发布 |
| 修改 JS 版本号 | 必须 -r(版本号同步 3 处后发布) | 否则生产缓存旧版 |
5.3 全部可调项
| 模式 | 版本号行为 | 观察方式 |
|---|---|---|
-r | 读 tools/.VERSION 递增并创建 git tag | git tag 多一个;页面 ?v= 变大 |
-c | 复用旧版本号 | tools/.VERSION 不变 |
5.4 边界与冲突
- 版本号同步 3 处(
tools/.VERSION、userConfig/_config.tmp.yml的{urlVersion}、userConfig/sw.tmp.js),漏一处会导致部分资源仍被缓存。 - 只改内容却用
-r会白白递增版本并让所有用户重新下载静态资源。
5.5 小结
- 改主题代码:
-r - 改文章:
-c(推送)或-d(预览) - 拿不准:先
git status --short看改的是哪个目录
6. 双仓库提交(子模块)
用途:主题在子模块
themes/matery/中,改主题后两个仓库都要提交,否则父仓库指向的仍是旧提交。学习路径:如何启用 → 常用选项 → 全部可调项 → 边界与冲突
6.1 如何启用
效果:子模块仓库多一个提交,父仓库多一个"更新子模块指针"的提交;父仓库的 git status 不再显示 themes/matery 有改动。
对应命令:
# 1. 提交子模块
git -C themes/matery add <files>
git -C themes/matery commit -m "[✨] feat(scope): 说明"
# 2. 提交父仓库(更新子模块指针)
git add themes/matery
git commit -m "[🔧] chore: 更新matery子模块指针"输出:两次 commit 各产生一个提交;git status 干净。
6.2 常用选项
本地提交规范:[emoji] type(scope): 描述,一个提交只做一件事。
| type | emoji | 用途 |
|---|---|---|
| feat | ✨ | 新功能 |
| fix | 🐛 | Bug 修复 |
| docs | 📖 | 文档变更 |
| refactor | ♻️ | 代码重构 |
| perf | ⚡ | 性能优化 |
| test | 🧪 | 测试相关 |
| chore | 🔧 | 构建/工具/配置 |
| style | 🎨 | 代码格式 |
6.3 全部可调项
| 仓库 | 路径 | 提交内容 |
|---|---|---|
| 子模块 | themes/matery/ | 主题代码改动 |
| 父仓库 | 仓库根 | 子模块指针 + 站点内容/脚本 |
6.4 边界与冲突
- 只提交父仓库不同步子模块 → 父仓库指针仍指向旧 commit,线上拿不到主题改动。
- 两个仓库的远程不同(gitea 主远程),推送时确认各自 remote。
6.5 小结
- 最小可用:子模块 commit → 父仓库 commit 指针
- 忘了第二步:父仓库
git status会一直显示子模块 modified - 提交信息:
[emoji] type(scope): 描述
7. Open Graph 元数据(open_graph)
用途:为页面生成 Open Graph 社交分享元数据(分享到微信/Twitter/Facebook 时显示标题、描述、缩略图)。
学习路径:如何启用 → 常用选项 → 全部可调项 → 边界与冲突
7.1 如何启用
效果:页面 <head> 里出现 og:title / og:description / og:image / twitter:card 等标签;把链接贴到社交平台,卡片显示标题、描述和缩略图。
对应配置(主题配置):
open_graph:
enable: true
twitter_card: summary_large_image # Twitter 卡片类型
twitter_id: # Twitter 用户 ID
twitter_site: # Twitter 站点 @用户名
google_plus: # Google+ 个人页
fb_admins: # Facebook 管理员 ID
fb_app_id: # Facebook App ID输出:构建后 public/posts/<abbrlink>/index.html 的 head 段含上述 meta 标签。
7.2 常用选项
① 默认分享图
效果:文章没有 img 时,首页/列表页的分享卡片用这张图;文章页仍优先用文章封面。
对应配置:
open_graph:
default_og_image: /medias_webp/featureimages/15.webp② 换 Twitter 卡片样式
效果:summary_large_image 显示大图卡片;summary 显示小图方卡。
对应配置:
open_graph:
twitter_card: summary7.3 全部可调项
| 键 | 类型 | 默认 | 可选值/范围 | 作用 |
|---|---|---|---|---|
open_graph.enable | bool | true | true / false | 生成 OG 标签 |
open_graph.twitter_card | string | summary_large_image | summary / summary_large_image | Twitter 卡片类型 |
open_graph.twitter_id | string | 空 | Twitter 用户 ID | 作者署名 |
open_graph.twitter_site | string | 空 | @用户名 | 站点账号 |
open_graph.fb_admins | string | 空 | Facebook 管理员 ID | FB 管理员 |
open_graph.fb_app_id | string | 空 | Facebook App ID | FB 应用 |
open_graph.default_og_image | string | — | 图片路径 | 无文章图时的回退图 |
7.4 边界与冲突
- 基于 Hexo 内置 open_graph helper;
enable: true时自动从文章 front-matter(title/description/cover)生成 OG 标签,社交平台分享时读取。 - 图片优先级:
page.img(文章图)→theme.default_og_image(默认图)→theme.featureImages[0]。 - 改了主题配置要同步改
userConfig/_config.tmp.yml,否则下次 CI 构建被覆盖。
7.5 小结
- 最小可用:
enable: true - 卡片没图:配
default_og_image - 大图卡片:
twitter_card: summary_large_image
8. 安全跳转页面(safego)
用途:外链跳转安全提示页——点击站外链接先经过本站提示页,避免直接跳转(防钓鱼/防追踪)。
学习路径:如何启用 → 常用选项 → 全部可调项 → 边界与冲突
8.1 如何启用
效果:点击站外链接先进入本站的安全提示页,用户确认后才离开本站;关闭时直接跳转到目标站点。
对应配置(主题配置):
safego:
enable: false输出:enable: true 时 scripts.ejs 引入 libs.js.safego(defer),css.ejs 额外预加载该脚本;false 时页面里没有这两个标签。
8.2 常用选项
① 开启 / 关闭
效果:true 拦截站外跳转并显示提示页;false(默认)保持原生跳转,不增加请求。
对应配置:
safego:
enable: true8.3 全部可调项
| 键 | 类型 | 默认 | 可选值/范围 | 作用 |
|---|---|---|---|---|
safego.enable | bool | false | true / false | 站外链接安全提示页开关 |
8.4 边界与冲突
- 依赖
libs.js.safego资源与safego样式,缺失时提示页无样式或脚本不生效。 - 参考实现见 Fluid 安全跳转。
8.5 小结
- 最小可用:
enable: true - 默认关闭:不想多一次点击就保持
false
附:部署速查表
| 场景 | 命令 |
|---|---|
| 本地预览 | tools/cicd.sh -d 或 npx hexo server -p 4100 |
| 仅内容推送 | tools/cicd.sh -c "说明" |
| 测试域验证 | tools/cicd.sh -t "说明" + make test-pwa |
| 正式发布 | tools/cicd.sh -r "特性" + tools/tests/release-test.sh |
| 本机快速构建 | tools/test.sh build |
| Docker 测试 | docker compose -f docker-compose.test.yml up -d && ... exec hexo bash |