外观
从 GitHub Pages 迁移到 Cloudflare Pages:一次博客发布链路整理
约 1360 字大约 5 分钟
2026-06-17
生成说明:本文由 OpenAI Codex(基于 GPT-5 的 AI 编程助手)辅助生成,并经整理后发布,生成时间为 2026/06/17。
今天把博客的部署链路从 GitHub Pages 迁到了 Cloudflare Pages。严格说,这不是一次“大迁移”,因为代码还在 GitHub,构建命令也没有变;真正变化的是:GitHub 退回到代码仓库本身,Cloudflare 接管构建、托管、域名、CDN、SSL 和访问统计。
这件事值得记一笔。因为很多折腾不是为了换一个更酷的名字,而是为了让后续每次发布都少一点绕路。
原来的状态
这个博客是 VuePress/Plume 项目,核心构建命令一直很简单:
pnpm docs:build构建产物在:
docs/.vuepress/dist以前的发布方式是 GitHub Actions 构建后,把静态文件推到 gh-pages 分支,再由 GitHub Pages 对外提供站点。Cloudflare 已经在前面做代理,所以访问链路大概是:
访问者 -> Cloudflare -> GitHub Pages这套方案当然能用,也用了很久。但它有一个小别扭:Cloudflare 负责 DNS/CDN/SSL/Web Analytics,GitHub Pages 负责托管,构建产物还要落到一个专门的 gh-pages 分支。链路不复杂,却有点分散。
既然域名和边缘网络都已经在 Cloudflare,不如把静态站点托管也一起交给 Cloudflare Pages。
迁移到 Cloudflare Pages
Cloudflare Pages 项目最终配置如下:
项目名:iworthy-github-io
仓库:iworthy/iworthy.github.io
生产分支:main
框架预设:None
构建命令:pnpm docs:build
输出目录:docs/.vuepress/dist环境变量单独指定了版本:
NODE_VERSION=22
PNPM_VERSION=10.27.0这里有个细节。Cloudflare Pages 的构建镜像支持通过环境变量指定 Node.js、pnpm 等版本,官方文档里也说明了 NODE_VERSION、PNPM_VERSION 这类变量的作用。既然本地 package.json 里已经使用 pnpm@10.27.0,云端最好也固定到同一版本,少一点“本地正常、线上抽风”的空间。
第一次部署成功后,Cloudflare 给了一个预览域名:
https://iworthy-github-io.pages.dev确认预览站点正常,再把正式域名 worthy.cc 绑定到 Pages 项目上。
根域名和 www
根域名切换时,Cloudflare 把原来指向 GitHub Pages 的 A/AAAA 记录替换成了 Pages 项目的 CNAME:
@ -> iworthy-github-io.pages.dev切换后用响应头验证:
curl -I https://worthy.cc/结果已经是 HTTP/2 200,响应头里只有 server: cloudflare,不再出现 GitHub Pages / Fastly 相关信息。
www.worthy.cc 也顺手处理掉。原来它还是:
www -> iworthy.github.io虽然它最终会 301 到根域名,但回源仍然经过 GitHub Pages。既然要收干净,就按照 Cloudflare 文档里“www 跳转到 apex”的思路处理:
- 建一个 Bulk Redirect 列表:
redirect_www_worthy_cc - 加一条规则:
www.worthy.cc301 到https://worthy.cc - 勾选保留 query、子路径匹配和保留路径后缀
- 创建并启用规则:
redirect_www_to_apex - DNS 里把
www改成已代理的占位 A 记录:
A www -> 192.0.2.1验证:
curl -I 'https://www.worthy.cc/test-path?from=www'返回:
HTTP/2 301
location: https://worthy.cc/test-path?from=www
server: cloudflare这就说明 www 的跳转已经由 Cloudflare 直接处理,路径和 query 也被保留下来了。
关掉 GitHub Pages
Cloudflare Pages 正常以后,旧的 GitHub Pages 就没有继续存在的必要了。
我先把原来的 GitHub Actions workflow 改成只允许手动触发:
on:
workflow_dispatch:这样它不会再因为 main 分支推送而自动构建、自动写入 gh-pages。如果以后真要临时回滚,还能手动跑一次。
随后在 GitHub 仓库设置里取消发布 Pages,并把 Pages 的 source branch 设置为 None。最后删除远端 gh-pages 分支:
git push origin --delete gh-pages再确认远端分支已经不存在:
git ls-remote --heads origin gh-pages没有输出,就说明删干净了。
后续发布流程
迁移之后,写文章的流程变得更直:
- 在
docs/blog/下新增或修改 Markdown。 - 本地构建验证:
pnpm docs:build- 提交并推送到
main:
git add <文章文件>
git commit -m "Add ..."
git push origin main- Cloudflare Pages 自动拉取 GitHub 仓库,执行
pnpm docs:build。 - 构建产物从
docs/.vuepress/dist发布到worthy.cc。
现在的链路变成:
GitHub 保存源码
Cloudflare Pages 构建和托管
Cloudflare DNS/CDN/SSL/Web Analytics 负责访问入口和统计少了 gh-pages 分支,也少了一段 GitHub Pages 的托管链路。
一点感受
这次整理最舒服的地方,不是“迁移成功”本身,而是职责终于清楚了。
GitHub 做它最擅长的事:保存代码、记录提交、触发集成。Cloudflare 做它最擅长的事:站在访问入口处,把构建、托管、缓存、证书和统计都收在一起。
很多系统刚开始都是“能跑就行”。能跑当然重要,但跑久了以后,架构里的小绕路会慢慢变成心智负担:这里有个旧分支,那里有个旧 workflow,域名指向和实际托管不完全一致,排查问题时脑子里要多绕一圈。
把这些东西理顺,不一定能让站点立刻变快很多,但会让下一次发布更笃定。
这就够了。