加载中...

加载中...

部署

本页讲解博客的发布与部署:静态产物如何托管、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 全部可调项

项类型默认可选值/范围作用
urlstring—站点完整 URLcanonical/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.githttps://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.gitVercel 生产项目-r / -cblog.17lai.site
hexoback.gitVercel 测试项目-t / -cblog2.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 / --testhexoback.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 taggit 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): 描述,一个提交只做一件事。

typeemoji用途
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: summary

7.3 全部可调项

键类型默认可选值/范围作用
open_graph.enablebooltruetrue / false生成 OG 标签
open_graph.twitter_cardstringsummary_large_imagesummary / summary_large_imageTwitter 卡片类型
open_graph.twitter_idstring空Twitter 用户 ID作者署名
open_graph.twitter_sitestring空@用户名站点账号
open_graph.fb_adminsstring空Facebook 管理员 IDFB 管理员
open_graph.fb_app_idstring空Facebook App IDFB 应用
open_graph.default_og_imagestring—图片路径无文章图时的回退图

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: true

8.3 全部可调项

键类型默认可选值/范围作用
safego.enableboolfalsetrue / 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
评论
数据加载中 ...