Files
blog/精简方案-只留CF和Hugo.md
T
zqlit e0218b42bb docs: 迁 CNB 前的架构决策文档 + 构建骨架
- 决策文档:架构总览 / 代码源与构建平台选型 / 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/(工作数据不入库)
2026-10-04 12:40:17 +08:00

229 lines
11 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 精简方案:只留 Cloudflare + Hugo
> 2026-10-04
> 目标:砍掉全部自建基础设施,只保留 **Hugo**(构建)和 **Cloudflare**(一切服务端)。
> 文中所有平台限制均来自官方文档核实,非推测。
---
## 一、决定一切的硬约束
**Cloudflare 唯一不能替你做的是「代码托管」。** 它的两条部署路线直接决定架构形态:
| 模式 | 代码源 | 构建在哪 | 适用场景 |
|---|---|---|---|
| **Git 集成** | **只认 github.com / gitlab.com**<br>(官方原文:*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 | 有国内节点,**不是问题** |
**两条硬结论:**
1. **CF 免费版在国内比国内 CDN 慢约 2–4 倍**(TTFB 0.6–0.9s vs 0.2–0.3s)。
2. **实测发现 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 为例)
1. GitLab.com 建**私有**项目 → 现有仓库推上去(`.git` 588MB,首次跨境推送需要时间)
2. CF Pages 新建项目 → **Connect to Git → 选 GitLab**
- 构建命令:`hugo --minify`
- 输出目录:`public`
- 环境变量:`HUGO_VERSION=0.128.2`(CF 构建镜像默认是 0.147.7,要锁到你的版本)
3. 绑定自定义域名 `usj.cc`
4. `blog-admin` 保持不动(本来就在 CF)
5. 停掉 Gitea / act_runner / 中转机的同步计划任务;DNS 切到 Cloudflare
6. **观察国内访问速度** —— 这是唯一的实质性风险点
## 附 B:形态 A 的落地顺序
1. 本机装 `hugo` 0.128.2 + `wrangler`(Node 环境已有)
2. CF Pages 新建 **Direct Upload** 项目(**注意:一旦选它,以后不能改成 Git 集成**)
3. 本机 `hugo --minify && npx wrangler pages deploy public --project-name=<项目名>`
4. 绑定域名,完成
5. 其余全部关停
---
## 附 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