- 决策文档:架构总览 / 代码源与构建平台选型 / CNB构建落地方案 / EdgeOne双区域 / Gitee / 阿里云ESA / 精简方案 - CNB 构建骨架:deploy/Dockerfile、bin/linux/hugo (84MB,linux/amd64 extended 0.128.2,供 CNB 容器 COPY 用) - scripts/setup-cnb-remotes.sh:双远端切换(CNB 主仓 + GitHub 备份) - .gitignore 补 .workbuddy/(工作数据不入库)
11 KiB
精简方案:只留 Cloudflare + Hugo
2026-10-04 目标:砍掉全部自建基础设施,只保留 Hugo(构建)和 Cloudflare(一切服务端)。 文中所有平台限制均来自官方文档核实,非推测。
一、决定一切的硬约束
Cloudflare 唯一不能替你做的是「代码托管」。 它的两条部署路线直接决定架构形态:
| 模式 | 代码源 | 构建在哪 | 适用场景 |
|---|---|---|---|
| Git 集成 | 只认 github.com / gitlab.com (官方原文:does not currently support connecting self-hosted instances) |
Cloudflare 侧自动构建 | 要「push 即上线」 |
| Direct Upload | 不需要 git | 不构建,你本地构建好推产物 | 要「零第三方依赖」 |
⚠️ 两种模式在项目创建时定死,事后不能互转(官方明说)。选错只能重建项目 —— 这是最容易踩的坑。 变通办法:建 Git 集成项目,之后在
Settings → Builds关掉「自动部署」,再用wrangler直传 —— 这样两种方式都能用(反过来不行)。
关键结论
GitHub 被封 ≠ 必须自建 Gitea。 你不需要「自建 git 托管」这种复杂度,只需要回答一个问题:
你要不要「不开电脑也能发文」?
二、两条路线
形态 A · 本地构建直传(最简,零第三方)
你的电脑 Cloudflare
┌─────────────────────┐ ┌──────────────┐
│ 写 md → hugo build │──wrangler─▶│ Pages (静态站) │
└─────────────────────┘ pages ├──────────────┤
deploy │ Workers (评论/RSS) │
└──────────────┘
- 组件数:1 台自己的电脑 + Cloudflare
- 第三方依赖:0(连 git 托管都不要)
- 发布链路:3 步,全在本机
- 代码备份:本地仓库即可,要冗余可推任意 git,或存 CF R2
- 代价:发文必须开电脑
形态 B · GitLab.com 当代码源 + CF 自动构建
写 md ──push──▶ gitlab.com ──自动构建──▶ Cloudflare Pages ──▶ 上线
Cloudflare Workers (评论/RSS)
- 组件数:gitlab.com + Cloudflare
- ★ 关键:构建跑在 Cloudflare 侧(免费 500 次/月、单次 20 分钟超时),不消耗 GitLab 的 400 分钟 → 所以之前担心的「GitLab 免费版 400 分钟/月不够用」在这套组合下根本不成立
- 额度核对:本站 3267 文件 / 最大单文件 12.8MB → CF 上限 20,000 文件 / 25MiB ✅ 完全够
- 代价:多一个外部账号
三、可以整个删掉的(9 项)
| # | 删掉的 | 原本的作用 |
|---|---|---|
| 1 | Gitea | 自建 git 托管(GitHub 被封后的替代品) |
| 2 | act_runner | 自建 CI runner |
| 3 | 广州中转机 + sync.sh |
每分钟轮询、把产物搬去又拍云 |
| 4 | 又拍云 | 国内源站 |
| 5 | 多吉云 | 国内 CDN,回源又拍云 |
| 6 | EdgeOne Pages | 境外线路托管 |
| 7 | 腾讯云 COS | 境外产物 → 国内的中转层 |
| 8 | artifact 传递链 | 跨 job 传 424MB(含 v3/v4 那串坑) |
| 9 | 兼容分支与冗余通知 | github.server_url 判断 ×8、TG/飞书/邮件三套、if:false 死代码约 100 行 |
发布链路从 7 环节降到 3 环节;需要自己运维的机器从 3 台降到 0 台。
四、Cloudflare 侧能白捡留下的
blog-admin/(artalk-cf 评论后端 + RSS 机器人)本来就是 CF Workers + D1 + KV —— 一行都不用改。
这是你现有架构里唯一「已经完全符合目标形态」的部分:
- 评论系统 →
api.200181.xyz,照常 - RSS 订阅抓取、友链朋友圈数据 → 照常
- 后台管理(
/admin/与/sidebar/)→ 照常
换句话说:你的「后端」其实早就已经是 Cloudflare 了,复杂的只是「发布管线」。
五、必须接受的代价(诚实说)
1. 国内访问会变慢 ← 最大的一笔
Cloudflare 免费版在中国大陆走境外节点(没有 ICP 备案就用不了大陆节点,China Network 要企业版)。 现在这套「又拍云 + 多吉云」的存在意义就是为了这个。
2026-10-04 国内机实测(腾讯云广州,见「五·补」章):CF 首字节 0.61–0.89s, 而现在的国内 CDN 是 0.18–0.32s —— 即 CF 比国内 CDN 慢约 2–4 倍。 能开、不算快,对个人博客通常可接受,但你要心里有数。
2. 写作后台(post.usj.cc)会没有
那套 Next.js 直接读写本地 .md 文件、依赖文件系统,CF 上跑不了。要么:
- 重写成 CF Worker(内容改存 R2/D1,图片存 R2)—— 你会写 Worker,技术可行,但是工作量
- 退回本地写作(配合形态 A 正好)
3. Telegram bot 发文、公众号发布会断
同理,需要重写成 CF Worker 才能保留。
4. 构建前的脚本要处理
check_links.js(友链检查)、generate_circle_data.js(朋友圈数据)、add_draft_to_hidden.py 这些:
- 要么塞进 CF Pages 的构建命令里(需要
npm ci,会拖慢构建、且 CF 构建环境要能装依赖) - 要么去掉(友情链接检查其实没必要每次构建都做)
五·补、国内访问能不能救?(2026-10-04 国内机实测)
用国内那台机器(腾讯云广州,119.29.215.187)实测,每项 3 次取代表值:
| 目标 | 首字节 TTFB | 连接建立 | 走哪个节点 |
|---|---|---|---|
usj.cc(现状:EdgeOne 国内节点) |
0.18–0.32s | 0.01–0.04s | 成都 / 浙江 |
api.200181.xyz(你自己的 CF Workers) |
0.61–0.89s | 0.20–0.45s | CF Anycast(IPv6) |
cravatar.cn(头像是 CF 的) |
0.65–0.71s | 0.23s | CF Anycast |
spst2.com(页首统计脚本) |
0.087s | 0.011s | 有国内节点,不是问题 |
两条硬结论:
- CF 免费版在国内比国内 CDN 慢约 2–4 倍(TTFB 0.6–0.9s vs 0.2–0.3s)。
- 实测发现 CF 的连接走了 IPv6(
2606:4700::…),握手要 0.20–0.45s; 同一时刻 IPv4 握手只要 0.058s。→ IPv6 到 CF 的路由在国内明显更差, 这是一个可以单独利用的抓手。
能加速的三条路
路 A · 官方(走不通) Cloudflare China Network 需要:Enterprise 企业版 + 单独订阅 + 每个主域名持有效 ICP 备案 + 京东云内容审核。个人博客没戏。
路 B · 社区「优选 IP」(有效,但违反 ToS) 原理:CF 用 Anycast 广播,大陆解析到的 IP 段路由差。做法是让大陆用户的 DNS 解析结果 指向另一段「对大陆友好」的 CF IP。
- 预期效果:按本机实测基线,合理预期是 0.6s → 0.2–0.3s(社区常说的「5s→2s」是针对更差的默认线)
- ⚠️ Pages 不能直接改 CNAME(会返回
1001)→ 必须「转成 Worker」或「交给第三方 DNS 分线路解析」 - ⚠️ 明文违反 CF 服务条款 2.2.1(b):causing traffic for your Cloudflare-proxied domain to be sent to an IP address that was not assigned by Cloudflare for the domain。 官方保留封号权;社区共识是「用别怕,怕别用」,建议账号隔离(主站一个号,优选另开小号)
- ⚠️ 要维护:优选 IP/域名会失效,得定期更换;个别优选域名还会被地方屏蔽
路 C · 不违规的优化(零风险,先做)
- ✅ 已做:字体自托管(
/font/zql-v2.woff2,无 Google Fonts)、CSS 合并成单文件、图片 WebP - 头像源
cravatar.cn走 CF(0.65s)→ 可换国内源(站内已有q1.qlogo.cn这类) - 加 Cache Rules 长缓存 + Early Hints + Tiered Cache(免费可用)→ 改善重复访问
- 若走第三方 DNS(路 B 顺带),只下发 A 记录、不下发 AAAA → 直接规避上面那条差的 IPv6 路由
一句话结论
你自己的实测就是答案:国内 CDN 快 2–4 倍,而且完全合规。 CF 免费版在国内的「加速」本质是可用的灰色技巧 + 持续维护成本。
- 如果「只留 CF」是硬目标 → 走 Worker + 第三方 DNS 只给 IPv4(比优选 IP 干净,且顺带修 IPv6 问题)
- 如果真正的目标是「砍复杂度」→ 记住:复杂度的大头在「构建与搬运」(Gitea / act_runner / 中转机 / COS / artifact), 不在 CDN 的数量。多留一个国内 CDN 不会让架构变复杂;砍掉那串搬运链才会。
六、我的建议
先回答那个问题:需不需要「不开电脑也能发文」?
| 你的答案 | 选 | 理由 |
|---|---|---|
| 不需要(本来就在电脑上写) | 形态 A | 真正的「只要 CF + Hugo」:0 台服务器、0 个第三方托管 |
| 需要(手机/TG 发文) | 形态 B | GitLab 只当「代码网盘 + 触发器」,构建和托管全在 CF |
两条都不要再去自建 Gitea —— 那正是你想摆脱的复杂度。
一个必须提前想清楚的点:CF Pages 的 Git 集成与 Direct Upload 不能互转,项目创建时就要定。 如果不确定,先建 Git 集成项目、之后关掉自动部署用 wrangler 直传,把两条路都留着。
七、如果还想更彻底(建议不要)
把内容也搬进 CF:文章存 R2/D1,写作后台写成 CF Worker。但 ——
Hugo 构建需要文件系统 + 执行二进制,跑不进 Worker。 所以要么放弃 Hugo(改成运行时渲染),要么保留一个构建执行者(那就回到形态 B 了)。复杂度会绕回来,不建议。
附 A:落地顺序(以形态 B 为例)
- GitLab.com 建私有项目 → 现有仓库推上去(
.git588MB,首次跨境推送需要时间) - CF Pages 新建项目 → Connect to Git → 选 GitLab
- 构建命令:
hugo --minify - 输出目录:
public - 环境变量:
HUGO_VERSION=0.128.2(CF 构建镜像默认是 0.147.7,要锁到你的版本)
- 构建命令:
- 绑定自定义域名
usj.cc blog-admin保持不动(本来就在 CF)- 停掉 Gitea / act_runner / 中转机的同步计划任务;DNS 切到 Cloudflare
- 观察国内访问速度 —— 这是唯一的实质性风险点
附 B:形态 A 的落地顺序
- 本机装
hugo0.128.2 +wrangler(Node 环境已有) - CF Pages 新建 Direct Upload 项目(注意:一旦选它,以后不能改成 Git 集成)
- 本机
hugo --minify && npx wrangler pages deploy public --project-name=<项目名> - 绑定域名,完成
- 其余全部关停
附 C:本方案的证据出处
- Cloudflare 官方文档 Git integration:「Pages offers support for GitHub and GitLab」「does not currently support connecting self-hosted instances of GitHub or GitLab」
- 同上:「You cannot switch to Direct Upload later」
- Cloudflare 官方文档 Direct Upload:Wrangler 上传上限 20,000 文件 / 25 MiB;拖拽上限 1,000 文件
- Cloudflare 官方文档 Workers Billing and Limitations:静态资源请求免费且不限量,20,000 文件 / 25 MiB
- Cloudflare Blog:Cloudflare Pages 现已提供对 GitLab 的支持
- CF Pages 免费额度:500 次构建/月、1 并发、单次 20 分钟超时
- 本站实测:
public/= 424MB / 3267 文件,最大单文件 12.8MB