background
一直显示?点击任意区域即可关闭
个性化配置

部署迁移执行方案

这份文档用于指导当前博客从“GitHub Pages 公开仓库部署”迁移到“支持私有仓库的部署架构”。

本方案的目标不是一次性重构所有服务,而是先解决源码公开问题,再逐步移除当前统计链路中对 GitHub 的运行时依赖。

当前推荐的迁移目标为:

  1. 前端站点:Vercel
  2. 统计 API:Vercel
  3. 域名和 DNS:Cloudflare
  4. PV / UV 存储:Upstash Redis
  5. 搜索:Algolia
  6. 源码仓库:GitHub 私有仓库

为什么采用这条迁移路线

当前工程已经具备明显的 Vercel 适配基础:

  1. 已存在 vercel.json
  2. 已存在 api/pv-dispatch.js
  3. package.json 中已提供 deploy:vercel 脚本
  4. 当前 Cloudflare 只承担域名和 CDN,不构成迁移障碍

如果现在直接改走 Cloudflare Pages 或 Workers,除了迁移部署,还要同步调整函数运行时和统计实现,风险会明显更高。

因此本次迁移优先采用:

  1. Vercel 托管前端和 API
  2. Cloudflare 保留域名管理和 DNS
  3. 后续再决定是否进一步去平台耦合

当前架构

当前博客部署结构如下:

  1. 前端站点:GitHub Pages
  2. 域名和 CDN:Cloudflare
  3. 统计中继 API:Vercel
  4. PV 存储:GitHub Issue 标题
  5. UV 存储:Upstash Redis
  6. 搜索:Algolia

当前这套结构的核心问题不在于静态站能不能部署,而在于统计链路仍然依赖 GitHub:

  1. 前端会匿名读取 GitHub Issue 获取 PV
  2. Vercel API 会向 GitHub 发起 repository_dispatch
  3. GitHub Actions 会把 Issue 标题中的 PV: N 改成 PV: N+1

这意味着:

  1. 只要仓库切为私有,前端直读 GitHub Issue 的逻辑就会失效
  2. 即使前端改到别的平台,GitHub 仍然是 PV 的实际存储和调度中心

当前关键文件

以下文件与迁移直接相关:

  1. themeConfig.mjs 用途:站点基础配置、搜索配置、GitHub 统计配置、dispatchProxy 地址。

  2. .vitepress/theme/components/Aside/Widgets/SiteData.vue 用途:侧边栏站点数据组件。当前负责读取 PV、生成 visitor_id、请求统计 API。

  3. api/pv-dispatch.js 用途:当前统计 API。负责 UV 去重与 GitHub repository_dispatch 转发。

  4. .github/workflows/update-pv.yml 用途:GitHub Actions 工作流。负责把 GitHub Issue 标题中的 PV 数字加 1。

  5. .github/workflows/deploy-pages.yml 用途:GitHub Pages 自动部署工作流。

  6. vercel.json 用途:Vercel 路由配置。用于保证静态页面重写和 /api 路由共存。

  7. PV_SETUP.md 用途:现有统计维护文档。迁移完成后需要同步更新。

  8. SEARCH_SETUP.md 用途:现有搜索维护文档。迁移期间需要确认域名变化不会影响 Algolia Crawler。

  9. public/CNAME 用途:当前生产域名基线,可用于核对域名绑定。

迁移目标架构

迁移完成后,建议采用以下结构:

  1. 私有 GitHub 仓库保存源码
  2. Vercel 从 GitHub 私有仓库自动拉取并构建 VitePress
  3. Cloudflare 继续管理 bbgs.xyzwww.bbgs.xyz
  4. 站点和统计 API 部署在同一个 Vercel 项目中
  5. 前端通过同域 /api/pv-dispatch 读取和更新统计数据
  6. PV 与 UV 都存入 Upstash Redis,不再依赖 GitHub Issue 与 GitHub Actions

迁移后的核心收益如下:

  1. 代码仓库可以改为私有
  2. 统计功能不再依赖公开 GitHub API
  3. 前端和 API 同域,跨域与配置复杂度降低
  4. 后续如果继续迁往 Cloudflare Workers,也会更容易

总体迁移原则

本次迁移遵循以下原则:

  1. 先迁部署,再迁统计,不做一步到位的大重构
  2. 每一阶段都需要可以回滚
  3. 搜索链路不在本轮强制改造范围内
  4. 在新链路稳定前,不直接关闭旧链路
  5. 所有平台环境变量必须先备份,再迁移

阶段划分

整个迁移建议拆分为六个阶段:

  1. 基线备份与迁移准备
  2. Vercel 接管前端部署
  3. 统计链路去 GitHub 化
  4. 前端配置切换到同域 API
  5. GitHub Pages 与 GitHub PV 工作流下线
  6. 文档与运维说明同步更新

下面按阶段展开说明。

第一阶段:基线备份与迁移准备

这一阶段不改代码,不切流量,只做记录和备份。

目标

建立当前生产环境的完整基线,确保后续任何一步都可以回滚。

必做事项

  1. 记录当前生产域名:

    • https://www.bbgs.xyz
    • https://bbgs.xyz
  2. 记录当前统计 API 地址:

    • 当前 dispatchProxy 指向的 Vercel 域名
  3. 记录当前 GitHub PV 数据:

    • 打开 PV 所在 Issue
    • 记录当前标题中的数值,例如 PV: 123
  4. 记录当前 Upstash UV 数据:

    • 当前 UV 总数 key
    • 当前访客集合 key
    • 当前 key 前缀
  5. 导出当前平台配置:

    • Vercel 环境变量
    • Upstash 凭据
    • Cloudflare DNS 记录
    • GitHub Actions 相关配置
  6. 确认本地可以成功构建:

    • 安装依赖
    • 执行构建
    • 确认 .vitepress/dist 正常产出

本阶段检查清单

  • [ ] 已记录当前线上域名
  • [ ] 已记录当前 Vercel API 地址
  • [ ] 已记录 GitHub Issue 当前 PV 数值
  • [ ] 已记录 Upstash UV 相关 key 和前缀
  • [ ] 已导出 Vercel 环境变量
  • [ ] 已核对 Cloudflare DNS 记录
  • [ ] 已验证本地构建成功

本阶段完成标准

当你能够回答以下问题时,说明第一阶段完成:

  1. 当前 PV 是多少
  2. 当前 UV key 是什么
  3. 当前生产域名如何解析
  4. 如果迁移失败,应该把流量切回哪里

第二阶段:Vercel 接管前端部署

这一阶段的目标是把静态站部署权从 GitHub Pages 迁到 Vercel,但暂时不改统计逻辑。

目标

让 Vercel 成为站点的新部署平台,同时保持 Cloudflare 作为域名入口。

推荐做法

  1. 在 Vercel 中导入当前 GitHub 仓库
  2. 选择生产分支,一般为 main
  3. 设置构建命令:
    • pnpm install --frozen-lockfile
    • pnpm run build
  4. 设置输出目录:
    • .vitepress/dist
  5. 保留 vercel.json 当前的静态重写策略
  6. 在 Vercel 中绑定生产域名
  7. 在 Cloudflare 中调整 DNS 指向 Vercel

本阶段注意事项

  1. 不要立刻删除 GitHub Pages 配置
  2. 先用 Vercel 预览域名验证站点可用
  3. 确保首页、文章页、归档页、分页页都能正常打开
  4. 确保自定义域名证书签发成功后再切正式流量

本阶段检查清单

  • [ ] 已在 Vercel 成功导入仓库
  • [ ] 已成功完成一次生产构建
  • [ ] 已在 Vercel 中配置自定义域名
  • [ ] 已在 Cloudflare 中配置正确的 DNS 指向
  • [ ] 已确认首页与文章页在 Vercel 可访问
  • [ ] GitHub Pages 仍可作为临时回滚入口

本阶段完成标准

从浏览器访问正式域名时,页面实际已经由 Vercel 提供,但 GitHub Pages 仍未下线。

第三阶段:统计链路去 GitHub 化

这是整个迁移中的关键阶段。

目标

把当前 PV 从 GitHub Issue 标题迁移到你自己的持久化存储中,并让前端不再访问 GitHub API。

当前问题

当前统计存在两个 GitHub 绑定点:

  1. 前端在 SiteData.vue 中直接请求 GitHub Issue 获取 PV
  2. api/pv-dispatch.js 仍会向 GitHub 发送 repository_dispatch

只要仓库改为私有,这两处至少有一处会直接出问题。

推荐改法

推荐把 PV 和 UV 都统一迁到 Upstash Redis。

原因如下:

  1. 当前 UV 已经在 Upstash Redis 中
  2. 现有服务端代码已经具备调用 Upstash REST API 的基础
  3. 不需要额外引入新的数据库平台
  4. 改动面最小,便于快速完成私有化迁移

建议的数据结构

可采用以下 key 设计:

  1. UV 去重集合:

    • bbgs:visitors:seen
  2. UV 总数:

    • bbgs:stats:uv:total
  3. PV 总数:

    • bbgs:stats:pv:total

如果你已经使用自定义前缀,则统一替换 bbgs

推荐改造方向

  1. 修改 api/pv-dispatch.js

    • 接收页面上报
    • 每次访问时把 PV 累加 1
    • 根据 visitor_id 判断 UV 是否新增
    • 在一次响应中返回最新 PV 与 UV
    • 不再请求 GitHub dispatches API
  2. 修改 SiteData.vue

    • 不再读取 GitHub Issue
    • 页面加载后直接请求同域统计 API
    • 从 API 响应中读取 PV 与 UV
  3. 停用 .github/workflows/update-pv.yml

    • 但先不要立刻删除,等验证稳定后再下线

本阶段风险控制

  1. 先保留旧 PV 数值,作为迁移初始化值
  2. 在 Redis 中手动写入初始 PV,避免迁移后从 0 开始
  3. 新接口上线后,先在预览环境验证,不直接切生产

本阶段检查清单

  • [ ] 已确定 PV 新存储 key
  • [ ] 已把旧 PV 数值迁入新存储
  • [ ] API 已支持同时返回 PV 与 UV
  • [ ] 前端已不再请求 GitHub Issue
  • [ ] API 已不再依赖 GitHub dispatch
  • [ ] 预览环境中 PV 与 UV 显示正常

本阶段完成标准

打开浏览器开发者工具后,站点不再访问 GitHub Issue API,也不再依赖 GitHub Actions 更新 PV。

第四阶段:前端配置切换到同域 API

统计链路完成后,需要把前端配置彻底切到新的同域接口模式。

目标

让前端只依赖当前站点域名下的 API,不再使用跨域的 Vercel 项目域名。

推荐改动

修改 themeConfig.mjs 中的统计配置:

  1. dispatchProxy 从完整 URL 改为:

    • /api/pv-dispatch
  2. 评估是否保留以下字段:

    • owner
    • repo
    • pageViewsIssueId
    • clientToken

如果统计链路已经完全去 GitHub 化,那么这些字段应逐步移除或至少停止使用。

本阶段注意事项

  1. 确保 vercel.json 的 rewrite 不会把 /api 改写到首页
  2. 确保同域请求不会再受到原来的 ALLOWED_ORIGIN 误配置影响
  3. 确保生产和预览环境都能访问统计接口

本阶段检查清单

  • [ ] dispatchProxy 已改成同域相对路径
  • [ ] 生产环境 API 可直接通过正式域名访问
  • [ ] 前端未再依赖 GitHub 相关配置项
  • [ ] 页面刷新后 PV 与 UV 均正常变化

本阶段完成标准

统计配置已经与 GitHub 仓库无关,站点与 API 由同一个部署平台统一提供。

第五阶段:GitHub Pages 与 GitHub PV 工作流下线

当前端、站点、统计都已经稳定后,才能进入这一步。

目标

正式移除 GitHub Pages 作为生产入口,并停止使用 GitHub Actions 维护 PV。

推荐顺序

  1. 确认 Vercel 生产部署稳定运行至少一段观察期
  2. 确认统计链路不再访问 GitHub API
  3. 停用或删除 .github/workflows/update-pv.yml
  4. 停用或删除 .github/workflows/deploy-pages.yml
  5. 最后再将 GitHub 仓库切为私有

为什么仓库私有化要放在最后

因为只要私有化动作先发生:

  1. 当前前端读取 GitHub Issue 的逻辑会先失效
  2. 一旦仍有遗漏的 GitHub 依赖,排查成本会更高

所以正确顺序应该是:

  1. 先让系统不依赖 GitHub 公开能力
  2. 再把仓库切为私有

本阶段检查清单

  • [ ] GitHub Pages 已不再承担生产流量
  • [ ] GitHub PV workflow 已停用
  • [ ] 仓库已切换为私有
  • [ ] 私有后站点访问正常
  • [ ] 私有后统计仍正常
  • [ ] 私有后搜索仍正常

本阶段完成标准

仓库已经是私有状态,正式域名正常可访问,统计与搜索不受影响。

第六阶段:文档与运维说明同步更新

迁移完成后,必须同步更新维护文档,否则后续排障会非常困难。

需要更新的文档

  1. PV_SETUP.md

    • 改写统计架构
    • 去掉 GitHub Issue 存储说明
    • 去掉 GitHub Actions 触发说明
    • 增加新 PV key、UV key、初始化方式和故障排查说明
  2. SEARCH_SETUP.md

    • 如果域名没有变化,一般只需确认 crawler 仍可抓取
    • 如果后续域名发生变化,需要更新 crawler 路径与验证信息
  3. 当前文档 MIGRATION_PLAN.md

    • 记录每一阶段的完成状态
    • 标记已完成与待完成事项

建议补充的运维内容

  1. Vercel 项目环境变量清单
  2. Upstash Redis key 结构说明
  3. Cloudflare DNS 记录说明
  4. 生产故障回滚流程

环境变量迁移清单

迁移时建议核对以下环境变量。

Vercel 需要保留的变量

  1. UPSTASH_REDIS_REST_URL
  2. UPSTASH_REDIS_REST_TOKEN
  3. UV_KEY_PREFIX
  4. ALLOWED_ORIGIN

Vercel 中可能下线的变量

当 PV 完全去 GitHub 化后,以下变量通常可以停用:

  1. GITHUB_PAT
  2. PV_OWNER
  3. PV_REPO
  4. PV_ISSUE_NUMBER

迁移建议

  1. 不要提前删除旧变量
  2. 等新统计链路稳定后再清理旧变量
  3. 在清理前记录变量用途,避免误删影响回滚

验证方案

每一阶段完成后,都应进行验证。

部署验证

  1. 首页可访问
  2. 文章详情页可访问
  3. portal 页面可访问
  4. 分页页面可访问
  5. RSS 和 sitemap 可访问

统计验证

  1. 打开页面后 PV 正常增加
  2. 同一浏览器重复访问时 UV 不异常增长
  3. 新设备或新浏览器访问时 UV 可增加
  4. 浏览器 Network 中不再出现 GitHub Issue API 请求
  5. 浏览器 Network 中不再出现 GitHub dispatch 请求

搜索验证

  1. 搜索框可以正常打开
  2. 文章搜索结果正常返回
  3. 新文章发布后,Crawler 仍能抓到

域名验证

  1. www.bbgs.xyz 可访问
  2. bbgs.xyz 可访问
  3. HTTPS 证书有效
  4. Cloudflare 代理开启后页面仍正常

私有仓库验证

  1. 仓库切为私有后,站点不报错
  2. 统计不报错
  3. 搜索不报错
  4. Vercel 自动部署仍正常触发

回滚方案

任何阶段出现问题,都必须能够快速回滚。

可回滚资源

  1. GitHub Pages 旧部署
  2. 旧的 GitHub PV 方案
  3. Cloudflare DNS 记录
  4. Vercel 上一个稳定版本

回滚原则

  1. 先恢复流量入口
  2. 再恢复统计链路
  3. 最后处理数据一致性

推荐回滚顺序

  1. 如果 Vercel 新部署异常:

    • 先回退到 Vercel 上一个稳定部署
  2. 如果 Vercel 平台整体不可用:

    • 在 Cloudflare 中把流量临时切回旧入口
  3. 如果新统计接口异常:

    • 暂时停用新统计逻辑
    • 恢复旧统计读取方式
    • 重新核对 Redis key 与环境变量

回滚前提

只有在第一阶段已经完整备份配置的前提下,回滚才可靠。

执行顺序总结

如果要按最稳妥的方式推进,请严格按下面顺序执行:

  1. 先备份当前生产配置和统计数据
  2. 再让 Vercel 接管前端部署
  3. 然后重构统计 API,把 PV 从 GitHub Issue 迁出
  4. 再切前端到同域 API
  5. 最后停用 GitHub Pages 和 GitHub PV workflow
  6. 确认一切稳定后,再把仓库切成私有

不要把“仓库切私有”提前到前面。

这是整个迁移过程中最容易导致站点统计直接失效的一步。

当前结论

基于当前项目结构,最适合你的迁移方案是:

  1. GitHub 私有仓库保存源码
  2. Vercel 负责前端和 API 部署
  3. Cloudflare 继续负责域名和 DNS
  4. Upstash Redis 同时承载 PV 和 UV
  5. Algolia 继续负责搜索

这条路线的优点是:

  1. 改动面最小
  2. 可分阶段推进
  3. 风险可控
  4. 最快解决源码公开问题

后续如果你想进一步统一平台,再单独评估是否把 Vercel API 迁往 Cloudflare Workers。