Files
blog/架构总览.md
T
zqlit b39dc29753 chore(远端): 移除 GitHub,改为「CNB 主仓 + Gitee 辅仓」
起因:GitHub 账号被平台标记,随后仓库被按 AUP 合规条款清空 ——
远端只剩一条孤立提交(无父提交、无内容):

    c21d5669  2026-10-06 20:08:32 +0800  zqlit
    chore: remove repository content (AUP compliance)

同时远端 main 的历史与本地**完全分叉**:两边只共享 2024-07-11 的 Initial commit,
之后每个提交 SHA 都不同(远端那份 989 提交、剥离了 .env/私钥/大二进制)。
所以 `git push gh main` 无法快进,也不可能再当备份用。

改动:

- `git remote remove gh`(改动前配置存 .workbuddy-backup/git-remotes.20261006-201354.txt)
- `pushall` 别名 → `git push origin main; git push gitee main`
- `scripts/setup-cnb-remotes.sh`:参数化第二个远端为 Gitee,
  顺带把「若残留 gh remote 就清掉」做进脚本;Gitee 凭据走 wincred
- `架构总览.md`:§2 发布旅程图、§5.2 远端表、§6 遗留待办全部改指向;
  新增 §5.2 的 GitHub 退役记录(含那条孤立提交的原文)
  与 §5.3「Gitee 辅仓的两条硬约束」实测核算
- `CNB构建落地方案.md`、`README.md`:远端与 pushall 说明同步
- **发布链路一起去 GitHub 化**(这几处原先都写死了 gh):
    · `deploy/editor-api/bootstrap.sh`  GH_URL/GH_SSH_KEY → GITEE_URL/GITEE_SSH_KEY,
      remote `gh` → `gitee`,known_hosts/私钥文件名跟着改;
      保留原设计:**没给私钥就自动降级成只推 origin**,不会让每次发布都报错
    · `docker-compose.editor.yml`   PUSH_REMOTES → origin,gitee
    · `editor-api/server.mjs`       默认值 → 'origin,gitee'
    · `editor-api/README.md`        变量表同步

★ 尚未解决 / 需要决策的两条 Gitee 硬约束(详见 架构总览.md §5.3):

1. **单文件 ≤ 50MB,而 `bin/linux/hugo` 是 83.1MB**
   —— 不管怎么瘦身历史,只要它还跟踪在 HEAD 里,Gitee 一律拒收。
2. 单仓库 ≤ 500MB,而 `.git` 是 620MB
   —— 移出那个 83MB 后 HEAD ≈ 374MB,才有余量。

另:线上 editor-api 容器的 .env 仍是 `PUSH_REMOTES=origin,gh`,
且仓库里还有一个 `gh` remote。因为推送逻辑对辅仓失败只警告、不阻断发布
(`git.mjs`:主仓成即算成),所以**线上发布没有坏**;
但要真正切到 Gitee,需要等 Gitee 仓库与私钥就位后再部署一次。
2026-10-06 20:18:29 +08:00

11 KiB
Raw Blame History

优世界博客 · 架构总览

更新时间:2026-10-04(CNB 迁移完成当日) 状态:迁移已落地并跑通(四线路全绿,单次发布约 3.5 分钟) 本文档只描述现状;迁移前的复杂度审计与选型过程见文末「相关文档」。


0. 一句话

四个子系统,一条 3 步的托管发布链路。构建与发布已从「自建 Gitea + act_runner + 广州中转机」迁到 腾讯云 CNB(cnb.cool) —— 需要自己运维的机器从 3 台降到 0 台。


1. 全景

1.1 四个子系统

# 子系统 技术栈 跑在哪 状态
1 内容系统 Hugo 0.128.2 extended + Ying 主题,138 篇 md;产物约 3200 文件 / 424MB 产物分发到 3 个 CDN 正常
2 评论系统 blog-admin/ = artalk-cf(Artalk v2 兼容服务端)+ RSS 机器人 Cloudflare Workers + D1 + KV → api.200181.xyz ✅ 零服务器零运维
3 写作系统 write-server/(Next.js 16,post.usj.cc)
write/(本地 Windows 前端)
独立 Docker 主机/本机 可用(两套前端功能重叠)
4 发布基础设施 CNB 流水线(.cnb.yml)+ 又拍云 + 多吉云 + EdgeOne 腾讯云 CNB(托管) 新建,已跑通

1.2 服务与地址地图

角色 地址 / 位置 说明
代码主仓 cnb.cool/zqlit/blog CNB,私有;构建由它触发
代码备份 github.com/zqlit/blog 仅作备份,不参与构建
构建 + 发布 CNB 流水线(腾讯云国内节点,4 核 8G) 托管,0 元(免费额度内)
密钥仓库 cnb.cool/zqlit/blog-secrets CNB「密钥仓库」类型,10 项变量经 imports 注入
境内源站 又拍云对象存储 由 CNB 国内节点直传(原为 if: false 的死代码)
国内加速 多吉云 CDN 回源又拍云
境外线路 EdgeOne Pages(项目 hugo-blog,--area overseas) 腾讯 EdgeOne 国际站
评论后端 api.200181.xyz Cloudflare Workers
通知 QQ 邮件(imql@qq.com) 已收敛为单一通道

关键点:境内、境外仍是两条独立线路,但由同一条流水线一次推完 —— 这是本次迁移最大的结构性改善。


2. 一次发布的完整旅程(3 步)

① 写作        write-server(网页) 或  write/(本地 Windows)
       │
② git push      git pushall  =  git push origin main ; git push gitee main
       │        ├─ origin → cnb.cool/zqlit/blog     (主仓,触发构建)
       │        └─ gitee  → gitee.com/…/blog        (辅仓,异地备份,不构建)
       ▼
③ CNB 流水线(国内节点,约 3.5 分钟,7 个 stage 顺序执行)
       ├─ 1. Hugo 构建          草稿隐藏预处理 → hugo --minify --gc → 算构建哈希
       ├─ 2. 同步到又拍云        upx sync(境内直传,非阻断但如实上报)
       ├─ 3. 刷新又拍云 CDN      purge 首页 + sitemap/rss/archives/posts 等固定入口
       ├─ 4. 刷新多吉云 CDN      node scripts/refresh_cdn.js
       ├─ 5. 部署 EdgeOne        edgeone pages deploy --area overseas
       ├─ 6. 上报部署状态        POST api.200181.xyz/api/deploy-status
       └─ 7. 邮件通知            成功 → stages 末尾;失败 → failStages

对照:迁移前是 7 步,中间有 3 个环节是你自己运维的服务器。


3. 流水线细节(.cnb.yml,284 行)

触发 条件 说明
push 推送到 main 主链路
crontab 0 9 * * *(Asia/Shanghai) 每天 09:00,与 push 共用同一组 stage(YAML 锚点)
机制 实现
构建镜像 deploy/Dockerfile,hugo 二进制随仓库携带(bin/linux/hugo,linux/amd64)
⚠️ docker 上下文 by: [bin/linux/hugo] —— CNB 的 docker build 只看得见 Dockerfile + by 列出的文件,漏写会报 not found
密钥注入 imports: https://cnb.cool/zqlit/blog-secrets/-/blob/main/secrets.yml
stage 间传状态 落盘 .ci_status(原版靠 needs.*.outputs)
并发控制 lock.cancel-in-progress(对应原 concurrency)
非阻断 又拍云三步 + 状态上报 + 邮件用 allowFailure: true,失败仍写状态如实上报
资源 cpus: 4(4 核 8G)

4. 迁移前后对比

维度 迁移前(Gitea 自建) 迁移后(CNB)
发布链路环节 7 步 3 步
自维护机器 / 服务 3 台(Gitea 主机 + act_runner + 广州中转机) 0(构建托管)
流水线定义 GitHub Actions 1169 行 .cnb.yml 284 行
产物传递 打 tar.zst → artifact → 中转机跨境下载 同一 pipeline 共享工作目录,无需传递
又拍云直传 if: false(境外 runner 必挂,从未跑通) 已跑通(国内节点直传)
COS 中转层 需要(存储 + 流量账单) 已砍
github.server_url 兼容分支 8 处 0
通知 3 套(TG / 飞书 / 邮件),约 400 行 1 套(邮件)
图片优化 + 反向 commit CI 内每轮白跑(15 张老图处理不掉) 未迁(如需保留,照搬 scripts/optimize_images.js)
构建环境 境外 VPS 腾讯云国内节点 4 核 8G
费用 VPS 月租 0 元(100GiB 仓库 + 160 核时/月)
单次发布耗时 — 约 3.5 分钟

原链路里那些补丁(COS 中转 / sync.sh 每分钟轮询 / artifact 打包 / 兼容分支) 唯一根因是「runner 在境外」。CNB 节点在国内,这一整层随之消失。


5. 运维要点

5.1 推送

git pushall        # 别名 = git push origin main; git push gitee main

用 ; 而非 && —— 一段失败不影响另一段(实测:串联 pushurl 时第一个失败会中止后续)。

5.2 远端

remote 地址 角色
origin https://cnb.cool/zqlit/blog.git 主仓(fetch + push,触发 CNB 构建)
gitee https://gitee.com/<用户名>/blog.git 辅仓(push,异地备份,不参与构建)
gitea 自建 23.254.236.47:3001 只读参考,稳定后手工删

⚠️ gh(GitHub)已于 2026-10-06 移除。 起因:GitHub 账号被平台标记,随后仓库被按 AUP 合规条款清空 —— 远端留下一条孤立提交(无父提交):

c21d5669 2026-10-06 20:08:32 +0800 zqlit <zqlit@users.noreply.github.com>
chore: remove repository content (AUP compliance)

同时远端 main 的历史与本地完全分叉(两边只共享 2024-07-11 的 Initial commit, 之后每个提交 SHA 都不同;远端那份是 989 提交、剥离了 .env/私钥/大二进制的变体)。 教训:别把「备份」寄托在会对内容做合规处置的平台上; 且一旦某次历史被重写,SHA 从此再也对不上。 远端配置的改动前快照留在 .workbuddy-backup/git-remotes.20261006-201354.txt。

5.3 Gitee 辅仓的两条硬约束(2026-10-06 实测核算)

约束 Gitee 免费版 本仓库当前 判定
单仓库容量 ≤ 500 MB .git 620 MB ❌ 超 24%
单文件大小 ≤ 50 MB bin/linux/hugo 83.1 MB ❌ 必删
用户总仓库容量 5 GB 620 MB ✅
私有仓协作人数 5 人 个人 ✅ 无关

bin/linux/hugo 这一条是硬门槛:它 83.1MB,超过单文件上限, 不管怎么瘦身历史,只要它还跟踪在 HEAD 里,Gitee 一律拒收。

体积分布(HEAD,实测 457.4 MB / 2509 文件):

目录 体积 说明
content/(含 posts/) ≈ 308 MB 博客正文与媒体(mp4/mp3/大图),搬不走
bin/linux/hugo 83.1 MB CNB 构建用的 hugo 二进制,可移出 git
static/ ≈ 38 MB 站点静态资源
themes/ 20.3 MB Ying 主题
其余全部 ≈ 8 MB 代码、文档、脚本

→ 移出 bin/linux/hugo 后 HEAD ≈ 374 MB,Gitee 有一份余量。

5.4 凭据

  • 令牌存仓库外:~/.workbuddy/secrets/cnb-token
  • 本仓 credential.helper 指向一个自定义脚本;.git/config 无明文
  • ⚠️ 本机全局 helper 是 GCM(会弹窗、对第三方 HTTPS 远端还会挂死);wincred 对 cnb.cool 有过「幽灵记录」删不掉 → 故用自定义 helper 绕开

5.5 密钥

  • 修改密钥 → 编辑 CNB 密钥仓库的 secrets.yml(网页编辑,禁 clone)
  • 本地 cnb-secrets.yml 只是粘贴草稿(已 gitignore,不入库)
  • ⚠️ CNB 的 imports 是一层映射(key 就是变量名本身);又拍云服务名在 CNB 里必须叫 UPYUN_SERVICE(旧 Gitea 里叫 UPYUN_BUCKET,照抄会「变量未定义」)

6. 遗留待办

# 项 说明
1 gh remote(GitHub) ✅ 已移除(2026-10-06)。GitHub 账号被标记、仓库被 AUP 清空,改以 Gitee 为辅仓
2 Gitee 辅仓 待办:①「个人设置 → 访问令牌」建令牌(勾 projects 读写);②建私有仓库;③git remote add gitee …;④解决 §5.3 的两条硬约束
3 bin/linux/hugo 出库 83.1MB,超 Gitee 单文件上限。需改为构建时获取(国内镜像 / CNB 对象存储),同时看 CNB 的 docker build by: 字段要跟着改
4 gitea remote 只读保留,稳定几天后 git remote remove gitea
5 GitHub 侧旧 workflow .github/workflows/*(deploy.yml 1169 行 + 两个辅助)已随 GitHub 一并退役,可删
6 令牌 scope 缺 repo-cnb-history:r(读构建日志);补上后 agent 可自行排错
7 Gitea 主机 / 广州中转机 发布链路已不依赖;是否退役取决于其它用途
8 README.md 仍写着旧 GitHub Actions 流程,待更新
9 敏感文件仍在跟踪中 .env、GITEA_SECRETS.md、write-server/nginx/ssl/privkey.pem、content/posts/2024/.../setup-secrets.png —— 推任何一个新平台前都应先 git rm --cached 并轮换凭据

附:相关文档

  • CNB构建落地方案.md — 迁移实施方案与实测数据
  • 代码源与构建平台选型.md — 平台对比(CNB / Gitee / GitLab / EdgeOne / 阿里云 ESA)
  • 砍COS改造步骤.md — COS 下线记录
  • EdgeOne双区域方案评估.md、Gitee方案评估.md、阿里云ESA评估.md、精简方案-只留CF和Hugo.md — 决策期评估

证据出处(现行):.cnb.yml(284 行)、deploy/Dockerfile、bin/linux/hugo、 scripts/send_mail.js、scripts/refresh_cdn.js、scripts/setup-cnb-remotes.sh。 已退役参考:.github/workflows/deploy.yml(1169 行)。