部署迁移执行方案
这份文档用于指导当前博客从“GitHub Pages 公开仓库部署”迁移到“支持私有仓库的部署架构”。
本方案的目标不是一次性重构所有服务,而是先解决源码公开问题,再逐步移除当前统计链路中对 GitHub 的运行时依赖。
当前推荐的迁移目标为:
- 前端站点:Vercel
- 统计 API:Vercel
- 域名和 DNS:Cloudflare
- PV / UV 存储:Upstash Redis
- 搜索:Algolia
- 源码仓库:GitHub 私有仓库
为什么采用这条迁移路线
当前工程已经具备明显的 Vercel 适配基础:
- 已存在 vercel.json
- 已存在 api/pv-dispatch.js
package.json中已提供deploy:vercel脚本- 当前 Cloudflare 只承担域名和 CDN,不构成迁移障碍
如果现在直接改走 Cloudflare Pages 或 Workers,除了迁移部署,还要同步调整函数运行时和统计实现,风险会明显更高。
因此本次迁移优先采用:
- Vercel 托管前端和 API
- Cloudflare 保留域名管理和 DNS
- 后续再决定是否进一步去平台耦合
当前架构
当前博客部署结构如下:
- 前端站点:GitHub Pages
- 域名和 CDN:Cloudflare
- 统计中继 API:Vercel
- PV 存储:GitHub Issue 标题
- UV 存储:Upstash Redis
- 搜索:Algolia
当前这套结构的核心问题不在于静态站能不能部署,而在于统计链路仍然依赖 GitHub:
- 前端会匿名读取 GitHub Issue 获取 PV
- Vercel API 会向 GitHub 发起
repository_dispatch - GitHub Actions 会把 Issue 标题中的
PV: N改成PV: N+1
这意味着:
- 只要仓库切为私有,前端直读 GitHub Issue 的逻辑就会失效
- 即使前端改到别的平台,GitHub 仍然是 PV 的实际存储和调度中心
当前关键文件
以下文件与迁移直接相关:
themeConfig.mjs 用途:站点基础配置、搜索配置、GitHub 统计配置、
dispatchProxy地址。.vitepress/theme/components/Aside/Widgets/SiteData.vue用途:侧边栏站点数据组件。当前负责读取 PV、生成visitor_id、请求统计 API。api/pv-dispatch.js 用途:当前统计 API。负责 UV 去重与 GitHub
repository_dispatch转发。.github/workflows/update-pv.yml 用途:GitHub Actions 工作流。负责把 GitHub Issue 标题中的 PV 数字加 1。
.github/workflows/deploy-pages.yml 用途:GitHub Pages 自动部署工作流。
vercel.json 用途:Vercel 路由配置。用于保证静态页面重写和
/api路由共存。PV_SETUP.md 用途:现有统计维护文档。迁移完成后需要同步更新。
SEARCH_SETUP.md 用途:现有搜索维护文档。迁移期间需要确认域名变化不会影响 Algolia Crawler。
public/CNAME用途:当前生产域名基线,可用于核对域名绑定。
迁移目标架构
迁移完成后,建议采用以下结构:
- 私有 GitHub 仓库保存源码
- Vercel 从 GitHub 私有仓库自动拉取并构建 VitePress
- Cloudflare 继续管理
bbgs.xyz和www.bbgs.xyz - 站点和统计 API 部署在同一个 Vercel 项目中
- 前端通过同域
/api/pv-dispatch读取和更新统计数据 - PV 与 UV 都存入 Upstash Redis,不再依赖 GitHub Issue 与 GitHub Actions
迁移后的核心收益如下:
- 代码仓库可以改为私有
- 统计功能不再依赖公开 GitHub API
- 前端和 API 同域,跨域与配置复杂度降低
- 后续如果继续迁往 Cloudflare Workers,也会更容易
总体迁移原则
本次迁移遵循以下原则:
- 先迁部署,再迁统计,不做一步到位的大重构
- 每一阶段都需要可以回滚
- 搜索链路不在本轮强制改造范围内
- 在新链路稳定前,不直接关闭旧链路
- 所有平台环境变量必须先备份,再迁移
阶段划分
整个迁移建议拆分为六个阶段:
- 基线备份与迁移准备
- Vercel 接管前端部署
- 统计链路去 GitHub 化
- 前端配置切换到同域 API
- GitHub Pages 与 GitHub PV 工作流下线
- 文档与运维说明同步更新
下面按阶段展开说明。
第一阶段:基线备份与迁移准备
这一阶段不改代码,不切流量,只做记录和备份。
目标
建立当前生产环境的完整基线,确保后续任何一步都可以回滚。
必做事项
记录当前生产域名:
https://www.bbgs.xyzhttps://bbgs.xyz
记录当前统计 API 地址:
- 当前
dispatchProxy指向的 Vercel 域名
- 当前
记录当前 GitHub PV 数据:
- 打开 PV 所在 Issue
- 记录当前标题中的数值,例如
PV: 123
记录当前 Upstash UV 数据:
- 当前 UV 总数 key
- 当前访客集合 key
- 当前 key 前缀
导出当前平台配置:
- Vercel 环境变量
- Upstash 凭据
- Cloudflare DNS 记录
- GitHub Actions 相关配置
确认本地可以成功构建:
- 安装依赖
- 执行构建
- 确认
.vitepress/dist正常产出
本阶段检查清单
- [ ] 已记录当前线上域名
- [ ] 已记录当前 Vercel API 地址
- [ ] 已记录 GitHub Issue 当前 PV 数值
- [ ] 已记录 Upstash UV 相关 key 和前缀
- [ ] 已导出 Vercel 环境变量
- [ ] 已核对 Cloudflare DNS 记录
- [ ] 已验证本地构建成功
本阶段完成标准
当你能够回答以下问题时,说明第一阶段完成:
- 当前 PV 是多少
- 当前 UV key 是什么
- 当前生产域名如何解析
- 如果迁移失败,应该把流量切回哪里
第二阶段:Vercel 接管前端部署
这一阶段的目标是把静态站部署权从 GitHub Pages 迁到 Vercel,但暂时不改统计逻辑。
目标
让 Vercel 成为站点的新部署平台,同时保持 Cloudflare 作为域名入口。
推荐做法
- 在 Vercel 中导入当前 GitHub 仓库
- 选择生产分支,一般为
main - 设置构建命令:
pnpm install --frozen-lockfilepnpm run build
- 设置输出目录:
.vitepress/dist
- 保留 vercel.json 当前的静态重写策略
- 在 Vercel 中绑定生产域名
- 在 Cloudflare 中调整 DNS 指向 Vercel
本阶段注意事项
- 不要立刻删除 GitHub Pages 配置
- 先用 Vercel 预览域名验证站点可用
- 确保首页、文章页、归档页、分页页都能正常打开
- 确保自定义域名证书签发成功后再切正式流量
本阶段检查清单
- [ ] 已在 Vercel 成功导入仓库
- [ ] 已成功完成一次生产构建
- [ ] 已在 Vercel 中配置自定义域名
- [ ] 已在 Cloudflare 中配置正确的 DNS 指向
- [ ] 已确认首页与文章页在 Vercel 可访问
- [ ] GitHub Pages 仍可作为临时回滚入口
本阶段完成标准
从浏览器访问正式域名时,页面实际已经由 Vercel 提供,但 GitHub Pages 仍未下线。
第三阶段:统计链路去 GitHub 化
这是整个迁移中的关键阶段。
目标
把当前 PV 从 GitHub Issue 标题迁移到你自己的持久化存储中,并让前端不再访问 GitHub API。
当前问题
当前统计存在两个 GitHub 绑定点:
- 前端在
SiteData.vue中直接请求 GitHub Issue 获取 PV - api/pv-dispatch.js 仍会向 GitHub 发送
repository_dispatch
只要仓库改为私有,这两处至少有一处会直接出问题。
推荐改法
推荐把 PV 和 UV 都统一迁到 Upstash Redis。
原因如下:
- 当前 UV 已经在 Upstash Redis 中
- 现有服务端代码已经具备调用 Upstash REST API 的基础
- 不需要额外引入新的数据库平台
- 改动面最小,便于快速完成私有化迁移
建议的数据结构
可采用以下 key 设计:
UV 去重集合:
bbgs:visitors:seen
UV 总数:
bbgs:stats:uv:total
PV 总数:
bbgs:stats:pv:total
如果你已经使用自定义前缀,则统一替换 bbgs。
推荐改造方向
修改 api/pv-dispatch.js
- 接收页面上报
- 每次访问时把 PV 累加 1
- 根据
visitor_id判断 UV 是否新增 - 在一次响应中返回最新 PV 与 UV
- 不再请求 GitHub
dispatchesAPI
修改
SiteData.vue- 不再读取 GitHub Issue
- 页面加载后直接请求同域统计 API
- 从 API 响应中读取 PV 与 UV
停用 .github/workflows/update-pv.yml
- 但先不要立刻删除,等验证稳定后再下线
本阶段风险控制
- 先保留旧 PV 数值,作为迁移初始化值
- 在 Redis 中手动写入初始 PV,避免迁移后从 0 开始
- 新接口上线后,先在预览环境验证,不直接切生产
本阶段检查清单
- [ ] 已确定 PV 新存储 key
- [ ] 已把旧 PV 数值迁入新存储
- [ ] API 已支持同时返回 PV 与 UV
- [ ] 前端已不再请求 GitHub Issue
- [ ] API 已不再依赖 GitHub dispatch
- [ ] 预览环境中 PV 与 UV 显示正常
本阶段完成标准
打开浏览器开发者工具后,站点不再访问 GitHub Issue API,也不再依赖 GitHub Actions 更新 PV。
第四阶段:前端配置切换到同域 API
统计链路完成后,需要把前端配置彻底切到新的同域接口模式。
目标
让前端只依赖当前站点域名下的 API,不再使用跨域的 Vercel 项目域名。
推荐改动
修改 themeConfig.mjs 中的统计配置:
将
dispatchProxy从完整 URL 改为:/api/pv-dispatch
评估是否保留以下字段:
ownerrepopageViewsIssueIdclientToken
如果统计链路已经完全去 GitHub 化,那么这些字段应逐步移除或至少停止使用。
本阶段注意事项
- 确保
vercel.json的 rewrite 不会把/api改写到首页 - 确保同域请求不会再受到原来的
ALLOWED_ORIGIN误配置影响 - 确保生产和预览环境都能访问统计接口
本阶段检查清单
- [ ]
dispatchProxy已改成同域相对路径 - [ ] 生产环境 API 可直接通过正式域名访问
- [ ] 前端未再依赖 GitHub 相关配置项
- [ ] 页面刷新后 PV 与 UV 均正常变化
本阶段完成标准
统计配置已经与 GitHub 仓库无关,站点与 API 由同一个部署平台统一提供。
第五阶段:GitHub Pages 与 GitHub PV 工作流下线
当前端、站点、统计都已经稳定后,才能进入这一步。
目标
正式移除 GitHub Pages 作为生产入口,并停止使用 GitHub Actions 维护 PV。
推荐顺序
- 确认 Vercel 生产部署稳定运行至少一段观察期
- 确认统计链路不再访问 GitHub API
- 停用或删除 .github/workflows/update-pv.yml
- 停用或删除 .github/workflows/deploy-pages.yml
- 最后再将 GitHub 仓库切为私有
为什么仓库私有化要放在最后
因为只要私有化动作先发生:
- 当前前端读取 GitHub Issue 的逻辑会先失效
- 一旦仍有遗漏的 GitHub 依赖,排查成本会更高
所以正确顺序应该是:
- 先让系统不依赖 GitHub 公开能力
- 再把仓库切为私有
本阶段检查清单
- [ ] GitHub Pages 已不再承担生产流量
- [ ] GitHub PV workflow 已停用
- [ ] 仓库已切换为私有
- [ ] 私有后站点访问正常
- [ ] 私有后统计仍正常
- [ ] 私有后搜索仍正常
本阶段完成标准
仓库已经是私有状态,正式域名正常可访问,统计与搜索不受影响。
第六阶段:文档与运维说明同步更新
迁移完成后,必须同步更新维护文档,否则后续排障会非常困难。
需要更新的文档
- 改写统计架构
- 去掉 GitHub Issue 存储说明
- 去掉 GitHub Actions 触发说明
- 增加新 PV key、UV key、初始化方式和故障排查说明
- 如果域名没有变化,一般只需确认 crawler 仍可抓取
- 如果后续域名发生变化,需要更新 crawler 路径与验证信息
当前文档 MIGRATION_PLAN.md
- 记录每一阶段的完成状态
- 标记已完成与待完成事项
建议补充的运维内容
- Vercel 项目环境变量清单
- Upstash Redis key 结构说明
- Cloudflare DNS 记录说明
- 生产故障回滚流程
环境变量迁移清单
迁移时建议核对以下环境变量。
Vercel 需要保留的变量
UPSTASH_REDIS_REST_URLUPSTASH_REDIS_REST_TOKENUV_KEY_PREFIXALLOWED_ORIGIN
Vercel 中可能下线的变量
当 PV 完全去 GitHub 化后,以下变量通常可以停用:
GITHUB_PATPV_OWNERPV_REPOPV_ISSUE_NUMBER
迁移建议
- 不要提前删除旧变量
- 等新统计链路稳定后再清理旧变量
- 在清理前记录变量用途,避免误删影响回滚
验证方案
每一阶段完成后,都应进行验证。
部署验证
- 首页可访问
- 文章详情页可访问
- portal 页面可访问
- 分页页面可访问
- RSS 和 sitemap 可访问
统计验证
- 打开页面后 PV 正常增加
- 同一浏览器重复访问时 UV 不异常增长
- 新设备或新浏览器访问时 UV 可增加
- 浏览器 Network 中不再出现 GitHub Issue API 请求
- 浏览器 Network 中不再出现 GitHub dispatch 请求
搜索验证
- 搜索框可以正常打开
- 文章搜索结果正常返回
- 新文章发布后,Crawler 仍能抓到
域名验证
www.bbgs.xyz可访问bbgs.xyz可访问- HTTPS 证书有效
- Cloudflare 代理开启后页面仍正常
私有仓库验证
- 仓库切为私有后,站点不报错
- 统计不报错
- 搜索不报错
- Vercel 自动部署仍正常触发
回滚方案
任何阶段出现问题,都必须能够快速回滚。
可回滚资源
- GitHub Pages 旧部署
- 旧的 GitHub PV 方案
- Cloudflare DNS 记录
- Vercel 上一个稳定版本
回滚原则
- 先恢复流量入口
- 再恢复统计链路
- 最后处理数据一致性
推荐回滚顺序
如果 Vercel 新部署异常:
- 先回退到 Vercel 上一个稳定部署
如果 Vercel 平台整体不可用:
- 在 Cloudflare 中把流量临时切回旧入口
如果新统计接口异常:
- 暂时停用新统计逻辑
- 恢复旧统计读取方式
- 重新核对 Redis key 与环境变量
回滚前提
只有在第一阶段已经完整备份配置的前提下,回滚才可靠。
执行顺序总结
如果要按最稳妥的方式推进,请严格按下面顺序执行:
- 先备份当前生产配置和统计数据
- 再让 Vercel 接管前端部署
- 然后重构统计 API,把 PV 从 GitHub Issue 迁出
- 再切前端到同域 API
- 最后停用 GitHub Pages 和 GitHub PV workflow
- 确认一切稳定后,再把仓库切成私有
不要把“仓库切私有”提前到前面。
这是整个迁移过程中最容易导致站点统计直接失效的一步。
当前结论
基于当前项目结构,最适合你的迁移方案是:
- GitHub 私有仓库保存源码
- Vercel 负责前端和 API 部署
- Cloudflare 继续负责域名和 DNS
- Upstash Redis 同时承载 PV 和 UV
- Algolia 继续负责搜索
这条路线的优点是:
- 改动面最小
- 可分阶段推进
- 风险可控
- 最快解决源码公开问题
后续如果你想进一步统一平台,再单独评估是否把 Vercel API 迁往 Cloudflare Workers。

