docs: 全量梳理文档结构;补 Gitea 迁移指南 / 架构精简候选;架构总览补证书管家子系统
用户四问:「把项目文件全部理一遍 还有readme文件」「gitea 后面可能还要迁移 帮我写一个迁移文档」
「证书管家做完了吗」「感觉现在架构还是复杂了」
一、文档梳理:根目录 15 个 md → 2 个
根目录只留 README.md(入口)+ 架构总览.md(现状唯一事实源),其余全部归位:
docs/
├── README.md ← 新增:文档地图(入口 / 当前有效 / 历史归档 三层)
├── 证书管家.md ← 原「函数版证书管家-方案.md」改名
│ (它早已是「现状+沿革」文档,标题名不副实 —— 签发早已不在 CF Worker)
├── Gitea迁移指南.md ← 新增
├── 架构精简候选.md ← 新增
├── CNB构建落地方案.md / GITEA_SECRETS.md
└── archive/{平台与选型,功能与修复,主题与内容}/ ← 32 份
- 32 个归档文档统一加 `> 📦 本文档已归档` banner,并指向架构总览
—— 这个仓库历史文档里全是「权威口径」,混看很容易拿废弃结论当现状
- gitea-backup/ → deploy/gitea/(原名「backup」不准,它是部署包;与其它 deploy 单元并列)
- 新增 md 链接校验(python 脚本,中文路径用 sed 不安全)→ 首轮 18 处断链
(多一层目录要让 banner 里的相对路径补一个 ../)→ 修正后 0 断链
二、新增 docs/Gitea迁移指南.md(★ 有死线:境外 VPS 11 月到期)
★ 核心价值是「指出迁移面已大幅缩小」:仓库原有的 deploy/gitea/迁移前检查清单.md
(2026-10-04)是为「Gitea + act_runner + 又拍云同步 *整套* 搬迁」写的,**那个前提已经不存在**——
构建归 CNB,runner / upyun-sync / 中转机 / COS 都不需要了。迁移实际只剩「搬数据卷 + 改地址」。
★★ 全文最重要:本仓有 9 处写死了旧地址,按易漏程度排序(1-3 本机,4-5 线上)
1 本机 .git/config 的 gitea remote
2 scripts/setup-cnb-remotes.sh 的 GITEA_URL 默认值
3 deploy/editor-api/bootstrap.sh 的 GITEA_URL 默认值
4 ★ /srv/editor-api/.env 的 GITEA_URL ← 漏了会「持续报错但只警告不阻断」,没人发现
5 ★ /srv/blog 的 gitea remote ← 同上
6 docs/GITEA_SECRETS.md
7-9 架构总览.md / README.md / editor-api/README.md
(不用改:docker-compose.editor.yml、server.mjs、pushall 别名 —— 只引用 remote 名字)
另含:建议新实例改用域名而非 IP(以后搬机器只改 DNS;⚠️ Gitea 28 起只读 ROOT_URL 不读
[server] DOMAIN);rsync 而非 dump(属主必须 uid/gid 1000);切换顺序「先建新的→验证→再拆旧的」;
验证清单强调 `git push gitea --dry-run`;第九节给出「干脆不留这个辅仓」的选项与判断依据。
顺带修掉两个硬伤:
- deploy/gitea/docker-compose.yml 的镜像 tag `1.28.0-rootless` 根本不存在
(Gitea 28 起去掉 1. 前缀)→ 改 28.0.0-rootless(pin 死,不用 latest)
- deploy/gitea/.gitignore 漏了 backups/(跑一次备份就会把含 secrets 的 dump 写进历史)
三、证书管家核实(结论:已上线运行,2 个遗留)
线上实测:容器 Up (healthy);/preflight 7/7 全过;3 组域名;下次自动续期 04:10。
遗留 ① writeapi.usj.cc 证书没纳管(真问题):nginx 配置在 /www/conf.d/writeapi.usj.cc.conf,
不在 /www/sites/ 管理树里 → 1Panel 的 ssl/upload+sslID 物化碰不到它。
实测仍是 RSA / CN=usj.cc / 到期 2026-12-07,本项目续期不会更新 → 12 月会断。
遗留 ② dnsapi.usj.cc 没上 HTTPS。
(澄清假问题:200181.xyz 公网看到的 LE 证书是 CF 自家边缘证书,与本项目无关)
四、新增 docs/架构精简候选.md(回应「架构还是复杂了」)
结论:复杂度不在件数,在「跨 6 个环境,其中 4 个要自己维护」。国内机 9 个容器里属于本项目的
只有 3 个,能动的只有 2 个。5 个候选 + 建议执行顺序:
1 停 certimate 容器(工作流已全停用)——先 stop 观察,别急着删
2 cn-dns-helper 大概率已是遗留(「Worker 侧签发」时代产物;现在签发在国内机且自带 dnsprovider,
/preflight 显示 CF 凭据可读;Worker 侧 dnsremoted.ts 已无任何引用)
3 Gitea:迁 or 不留
4 两套写作前端收敛(本轮不动,先看使用频率)
5 writeapi.usj.cc 证书纳管(12 月死线)
并明确列出 6 项「必要复杂度,不建议动」。
五、架构总览补齐证书管家子系统(★ 之前完全缺席)
一个完整子系统在「事实源文档」里一个字都没有 —— 这本身就是文档债。补:
- §0 一句话(四→五个子系统)、§1.1 子系统表、§1.2 地址地图两行
- **新增 §5.7 证书管家**:职责划分 / 为什么非要这么分(Worker 免费版 CPU 10ms)/
三条不能破的红线(Worker 不得签发 · 证书路由只认 Bearer 会话 · 角色必须正着枚举放行)/
纳管域名表 / 与 certimate 的关系 / 已知遗留
- .cnb.yml 行数 284 → 337(数字漂了);头部更新时间 → 2026-10-06;附录表改指 docs/
- §6 待办:#13(证书遗留)、#14(复杂度盘点)新增;#7 改写为「Gitea 11 月到期,★ 有死线」
六、记忆
.workbuddy/memory/MEMORY.md 新增「文档结构」「Gitea 迁移死线」两节;证书管家节补实测与遗留。
This commit is contained in:
1 parent
d3da972c3b
commit
7abef4ac13
48 files changed
+780
-98
No files matched your search
@@ -1,20 +1,25 @@
|
|||||||
# 优世界博客(usj.cc)
|
# 优世界博客(usj.cc)
|
||||||
|
|
||||||
Hugo 静态博客 + 自研评论后端 + 写作后台。
|
Hugo 静态博客 + 自研评论后端 + 写作后台 + 证书管家。
|
||||||
**构建与发布跑在腾讯云 CNB**(国内节点),单次发布约 3.5 分钟,境内/境外两条线路一次推完。
|
**构建与发布跑在腾讯云 CNB**(国内节点),单次发布约 3.5 分钟,境内/境外两条线路一次推完。
|
||||||
|
|
||||||
> 架构全貌、迁移前后对比、运维要点 → [`架构总览.md`](架构总览.md)
|
> 📖 **想先看懂全局** → [`架构总览.md`](架构总览.md)(架构唯一事实源)
|
||||||
|
> 🗂 **想找某份文档** → [`docs/README.md`](docs/README.md)(文档地图)
|
||||||
|
> 🔧 **要动手改东西** → 先看下面「项目构成」找准子系统,再看对应的专题文档
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 一、项目构成
|
## 一、项目构成(五个子系统)
|
||||||
|
|
||||||
| 子系统 | 位置 | 技术栈 |
|
| # | 子系统 | 位置 | 技术栈 | 部署形态 |
|
||||||
|---|---|---|
|
|---|---|---|---|---|
|
||||||
| **内容** | `content/`、`themes/Ying/` | Hugo 0.128.2 extended + Ying 主题 |
|
| 1 | **内容** | `content/`、`themes/Ying/` | Hugo 0.128.2 extended + Ying 主题 | 产物分发到 3 个 CDN |
|
||||||
| **评论后端** | `blog-admin/` | artalk-cf:Cloudflare Workers + D1 + KV(`api.200181.xyz`) |
|
| 2 | **评论后端** | `blog-admin/` | artalk-cf:Cloudflare Workers + D1 + KV | 托管(`api.200181.xyz`) |
|
||||||
| **写作后台** | `write-server/`(线上 `post.usj.cc`)、`write/`(本地 Windows) | Next.js |
|
| 3 | **写作后台** | `write-server/`(线上 `post.usj.cc`)、`write/`(本地)、`editor-api/`(线上发布入口) | Next.js / 轻量 Node(零依赖) | 独立主机 / 本机 / 国内机容器 |
|
||||||
| **发布** | `.cnb.yml`、`deploy/` | CNB 流水线 + Dockerfile |
|
| 4 | **发布基础设施** | `.cnb.yml`、`deploy/Dockerfile` | CNB 流水线 + 又拍云 + 多吉云 + EdgeOne | 托管(CNB,0 元额度内) |
|
||||||
|
| 5 | **证书管家** | `deploy/cn-certkeeper/`、`blog-admin/src/lib/acme.ts` | 自研 ACME 客户端(纯 WebCrypto,零 npm 依赖) | 国内机容器(签发)+ CF Worker(只读) |
|
||||||
|
|
||||||
|
> 子系统 5 的详细设计与「勿回退的坑」见 [`docs/证书管家.md`](docs/证书管家.md)。
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -22,22 +27,35 @@ Hugo 静态博客 + 自研评论后端 + 写作后台。
|
|||||||
|
|
||||||
```
|
```
|
||||||
blog/
|
blog/
|
||||||
├── .cnb.yml # ★ CNB 流水线(push + 每日定时)
|
├── README.md # ★ 本文(项目入口)
|
||||||
├── deploy/Dockerfile # 构建镜像(hugo 二进制由 bin/linux/hugo 提供)
|
├── 架构总览.md # ★ 架构唯一事实源
|
||||||
├── bin/linux/hugo # Hugo extended 0.128.2(linux/amd64,供 CNB 构建用)
|
├── docs/ # 专题文档(地图见 docs/README.md)
|
||||||
├── content/
|
│ ├── 证书管家.md
|
||||||
│ ├── posts/<年>/<日期>-<标题>/ # 文章(Page Bundle,index.md + 图片)
|
│ ├── Gitea迁移指南.md # ★ Gitea 换机器时照做
|
||||||
│ ├── about.md / links.md / circles.md / archives.md
|
│ ├── CNB构建落地方案.md
|
||||||
├── themes/Ying/ # 主题(layout / assets / data)
|
│ ├── GITEA_SECRETS.md # ⚠️ 含明文凭据
|
||||||
├── static/ # 原样复制进产物(emotion 表情、image、js …)
|
│ └── archive/ # 已归档:决策期评估 + 已完结方案
|
||||||
├── blog-admin/ # 评论后端(artalk-cf)
|
├── .cnb.yml # CNB 流水线(push 触发 + 每日定时)
|
||||||
├── write-server/ # 线上写作后台
|
├── content/ # 文章(Page Bundle:index.md + 图片)
|
||||||
├── write/ # 本地写作前端
|
├── themes/Ying/ # 主题
|
||||||
├── scripts/ # 各类工具脚本(见第六节)
|
├── static/ # 原样复制进产物(表情、图片、js …)
|
||||||
├── hugo.toml # Hugo 主配置
|
├── hugo.toml # Hugo 主配置
|
||||||
└── 架构总览.md # ★ 架构文档
|
├── bin/linux/hugo # Hugo extended 0.128.2(linux/amd64,供 CNB 构建用)
|
||||||
|
├── blog-admin/ # 评论后端(artalk-cf)+ 证书管家的只读面
|
||||||
|
├── editor-api/ # 写作后台的后端(国内机容器里跑的就是它)
|
||||||
|
├── write-server/ # 线上写作前端(Next.js)
|
||||||
|
├── write/ # 本地写作前端(Windows)
|
||||||
|
├── deploy/ # 部署单元
|
||||||
|
│ ├── Dockerfile # CNB 构建镜像
|
||||||
|
│ ├── editor-api/ # bootstrap.sh(一键部署写作后台)
|
||||||
|
│ ├── cn-certkeeper/ # 证书签发 + 部署容器
|
||||||
|
│ ├── cn-dns-helper/ # DNS-01 辅助
|
||||||
|
│ └── gitea/ # Gitea 部署包(原名 gitea-backup/)
|
||||||
|
└── scripts/ # 工具脚本(见第五节)
|
||||||
```
|
```
|
||||||
|
|
||||||
|
> `data/`、`public/`、`.editor-tmp/`、`.workbuddy-backup/` 等为运行时/构建期产物,**已被 `.gitignore` 忽略**。
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 三、内容写作
|
## 三、内容写作
|
||||||
@@ -79,70 +97,56 @@ hugo server -D # 含草稿
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 四、发布流程
|
## 四、发布与留存
|
||||||
|
|
||||||
|
### 4.1 一次发布(3 步)
|
||||||
|
|
||||||
```
|
```
|
||||||
写作(write-server / write/)
|
① 写作 write-server(网页)或 write/(本地 Windows)
|
||||||
│ git pushall (= git push origin main ; git push gitea main)
|
│
|
||||||
|
② git push git pushall = git push origin main ; git push gitea main
|
||||||
|
│ ├─ origin → cnb.cool/zqlit/blog (主仓,触发构建)
|
||||||
|
│ └─ gitea → 23.254.236.47:3001/zqlit/blog (自建 Gitea 辅仓,只推不拉)
|
||||||
▼
|
▼
|
||||||
origin → CNB 主仓 zqlit/blog ──触发──► CNB 流水线(国内节点,约 3.5 分钟)
|
③ CNB 流水线(国内节点,约 3.5 分钟)
|
||||||
├─ Hugo 构建
|
├─ Hugo 构建 → 同步又拍云 → 刷新又拍云 CDN → 刷新多吉云 CDN
|
||||||
├─ 同步到又拍云(境内源站)
|
└─ 部署 EdgeOne Pages(境外线路)→ 上报状态 → 邮件通知
|
||||||
├─ 刷新又拍云 CDN
|
|
||||||
├─ 刷新多吉云 CDN
|
|
||||||
├─ 部署 EdgeOne Pages(境外线路)
|
|
||||||
└─ 邮件通知
|
|
||||||
|
|
||||||
gitea → 自建 Gitea(23.254.236.47:3001) 代码同步辅仓:只推不拉、不参与构建
|
|
||||||
```
|
```
|
||||||
|
|
||||||
- **推送**:`git pushall` —— 依次推 `origin`(CNB 主仓,触发构建)与 `gitea`(自建 Gitea 代码同步辅仓)
|
- **触发**:推送到 `main`;另有每日 `0 9 * * *`(北京时间)定时构建
|
||||||
;只推主仓用 `git push origin main`
|
- **密钥**:全部来自 CNB 密钥仓库 `zqlit/blog-secrets`,经 `.cnb.yml` 的 `imports` 注入
|
||||||
|
—— **仓库里没有任何明文密钥**
|
||||||
|
- 改动 `main` 即自动上线,本地无需构建
|
||||||
|
|
||||||
|
### 4.2 三个留存层(失效模式不同,不能互相替代)
|
||||||
|
|
||||||
|
| 层 | 载体 | 保住什么 | 依赖 |
|
||||||
|
|---|---|---|---|
|
||||||
|
| **主仓** `origin` | CNB | 源码 + 触发构建 | CNB 平台 |
|
||||||
|
| **代码辅仓** `gitea` | 自建 Gitea | 在线可 clone、可按提交追溯 | 自己的机器(⚠️ **2026 年 11 月到期,要迁**,见 `docs/Gitea迁移指南.md`) |
|
||||||
|
| **离线备份** | 中兴 F50 / OpenList | 完整历史 + 所有对象(加密单文件) | 家庭局域网 |
|
||||||
|
|
||||||
|
- **推送**:`git pushall` 依次推 `origin` 与 `gitea`;只推主仓用 `git push origin main`
|
||||||
- 线上写作后台(国内机 `editor-api` 容器)走同一套:`PUSH_REMOTES=origin,gitea`,
|
- 线上写作后台(国内机 `editor-api` 容器)走同一套:`PUSH_REMOTES=origin,gitea`,
|
||||||
**主仓成功即算发布成功**,辅仓失败只警告不阻断
|
**主仓成功即算发布成功**,辅仓失败只警告不阻断
|
||||||
- ★ **两边同一条铁律:任何提交都必须先落到 CNB** —— pull 源只有 `origin`,
|
- ★ **两边同一条铁律:任何提交都必须先落到 CNB** —— pull 源只有 `origin`,
|
||||||
只推 `gitea` 的提交后台看不见,下次发布会因 non-fast-forward 被拒
|
只推 `gitea` 的提交后台看不见,下次发布会因 non-fast-forward 被拒
|
||||||
- **备选异地备份**:**不走 git 远端**。本机计划任务每天 03:30 把整仓 bundle
|
- **离线备份**:本机计划任务每天 03:30 把整仓 bundle(**打包前先 `git fetch --all`**,
|
||||||
(**打包前先 `git fetch --all`**,否则备的是过期快照)加密后传到中兴 F50 上的
|
否则备的是过期快照)加密后传到 F50 上的 OpenList(见 `架构总览.md` §5.6)
|
||||||
OpenList(见 `架构总览.md` §5.6)
|
|
||||||
- **触发**:推送到 `main`;另有每日 `0 9 * * *`(北京时间)定时构建
|
|
||||||
- **密钥**:全部来自 CNB 密钥仓库 `zqlit/blog-secrets`,经 `.cnb.yml` 的 `imports` 注入,
|
|
||||||
**仓库里没有任何明文密钥**
|
|
||||||
- 改动 `main` 即自动上线,本地无需构建
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 五、三个子系统
|
## 五、常用脚本(`scripts/`)
|
||||||
|
|
||||||
### 内容系统
|
|
||||||
|
|
||||||
Hugo + Ying 主题。`hugo.toml` 控站点信息、永久链接、Artalk 地址、弹幕等。
|
|
||||||
|
|
||||||
### 评论系统(`blog-admin/`)
|
|
||||||
|
|
||||||
自研的 **Artalk v2 兼容服务端**,跑在 Cloudflare Workers + D1(SQLite)+ KV:
|
|
||||||
|
|
||||||
- 前端用官方 Artalk 客户端(`themes/Ying/assets/js/libs/Artalk.js`,本地打包,非 CDN)
|
|
||||||
- 后端 API 基址 `https://api.200181.xyz`(评论 `/api/v2/*` 与 RSS 订阅 `/api/*` 同一 Worker)
|
|
||||||
- 部署:`cd blog-admin && npm run deploy`(详细步骤见 `blog-admin/README.md`、`部署清单.md`)
|
|
||||||
|
|
||||||
### 写作后台
|
|
||||||
|
|
||||||
- `write-server/`:线上版(Next.js),部署在独立主机
|
|
||||||
- `write/`:本地 Windows 版
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 六、常用脚本(`scripts/`)
|
|
||||||
|
|
||||||
| 脚本 | 用途 | 在哪跑 |
|
| 脚本 | 用途 | 在哪跑 |
|
||||||
|---|---|---|
|
|---|---|---|
|
||||||
| `add_draft_to_hidden.py` | 构建前把 `status: hidden` 转成草稿 | **CI** |
|
| `add_draft_to_hidden.py` | 构建前把 `status: hidden` 转成草稿 | **CI** |
|
||||||
| `refresh_cdn.js` | 刷新多吉云 CDN(零依赖) | **CI** |
|
| `refresh_cdn.js` | 刷新多吉云 CDN(零依赖) | **CI** |
|
||||||
| `send_mail.js` | 构建结果邮件通知(零依赖 SMTP) | **CI** |
|
| `send_mail.js` | 构建结果邮件通知(零依赖 SMTP) | **CI** |
|
||||||
| `setup-cnb-remotes.sh` | 切换/重建 git 远端(CNB 主仓 + 自建 Gitea 辅仓;顺手清掉退役远端) | 本机 |
|
| `fetch_snapshots.sh` | 构建期拉 conf/友链/友圈快照 → `data/` | **CI** |
|
||||||
| `backup-run.mjs` | 备份的推荐入口:跑 `backup-bundle` + **失败时发告警邮件** | 本机/计划任务 |
|
| `setup-cnb-remotes.sh` | 重建 git 远端(CNB 主仓 + Gitea 辅仓;顺手清退役远端) | 本机 |
|
||||||
| `backup-bundle.mjs` | `git fetch --all` → 整仓 bundle → AES-256-GCM 加密 → WebDAV 传中兴 F50(见 架构总览 §5.6) | 本机/计划任务 |
|
| `backup-run.mjs` | 备份推荐入口:跑 `backup-bundle` + **失败时发告警邮件** | 本机/计划任务 |
|
||||||
|
| `backup-bundle.mjs` | `git fetch --all` → 整仓 bundle → AES-256-GCM 加密 → WebDAV 传 F50 | 本机/计划任务 |
|
||||||
| `backup-task.cmd` | 上面的计划任务入口(每天 03:30;**内容必须全 ASCII**) | 计划任务 |
|
| `backup-task.cmd` | 上面的计划任务入口(每天 03:30;**内容必须全 ASCII**) | 计划任务 |
|
||||||
| `optimize_images.js` | 图片批量压缩优化 | 本机 |
|
| `optimize_images.js` | 图片批量压缩优化 | 本机 |
|
||||||
| `generate_circle_data.js` | 抓友链 RSS 生成朋友圈数据 | 本机 |
|
| `generate_circle_data.js` | 抓友链 RSS 生成朋友圈数据 | 本机 |
|
||||||
@@ -155,13 +159,17 @@ Hugo + Ying 主题。`hugo.toml` 控站点信息、永久链接、Artalk 地址
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 七、相关文档
|
## 六、文档地图
|
||||||
|
|
||||||
|
只列导航,完整说明见 [`docs/README.md`](docs/README.md)。
|
||||||
|
|
||||||
| 文档 | 内容 |
|
| 文档 | 内容 |
|
||||||
|---|---|
|
|---|---|
|
||||||
| `架构总览.md` | **当前架构全貌**(子系统、发布链路、迁移前后对比、运维要点) |
|
| [`架构总览.md`](架构总览.md) | ★ **当前架构全貌**(五个子系统、发布链路、运维要点、遗留待办) |
|
||||||
| `CNB构建落地方案.md` | 迁 CNB 的实施方案与实测数据 |
|
| [`docs/证书管家.md`](docs/证书管家.md) | ★ 证书子系统:现状 + 决策沿革 + 勿回退的坑 |
|
||||||
| `代码源与构建平台选型.md` | 平台对比(CNB / Gitee / GitLab / EdgeOne / 阿里云 ESA) |
|
| [`docs/Gitea迁移指南.md`](docs/Gitea迁移指南.md) | ★ Gitea 换机器:**本仓 9 处写死旧地址**的清单 + 验证步骤 |
|
||||||
| `砍COS改造步骤.md` | 腾讯云 COS 下线记录 |
|
| [`docs/架构精简候选.md`](docs/架构精简候选.md) | 复杂度盘点与 5 个可精简候选(想「让架构简单点」时看) |
|
||||||
| `blog-admin/README.md` | 评论后端完整说明 |
|
| [`docs/CNB构建落地方案.md`](docs/CNB构建落地方案.md) | 迁 CNB 的实施方案与实测数据 |
|
||||||
| `blog-admin/部署清单.md` | 评论后端部署步骤 |
|
| [`docs/archive/`](docs/archive/) | 决策期评估与已完结方案(**不代表现状**) |
|
||||||
|
| `blog-admin/README.md`、`blog-admin/部署清单.md` | 评论后端完整说明 |
|
||||||
|
| `editor-api/README.md` | 写作后台 API(含「落盘:写一次,存三处」) |
|
||||||
File renamed without changes.
@@ -7,5 +7,10 @@
|
|||||||
# 数据卷(迁移时单独打包,不进 git)
|
# 数据卷(迁移时单独打包,不进 git)
|
||||||
data/
|
data/
|
||||||
|
|
||||||
|
# ★ 2026-10-06 补:backup.sh 的产物落在 backups/,含 secrets 与完整 data 卷
|
||||||
|
# (gitea.db / app.ini / runner 凭据)。原先漏了这一条,跑一次备份再 `git add .`
|
||||||
|
# 就会把凭据写进历史。
|
||||||
|
backups/
|
||||||
|
|
||||||
# write-server 运行时产物(若纳入)
|
# write-server 运行时产物(若纳入)
|
||||||
*.log
|
*.log
|
||||||
@@ -1,4 +1,22 @@
|
|||||||
# Gitea 可移植部署包
|
# Gitea 部署包
|
||||||
|
|
||||||
|
> ⚠️ **2026-10-06 更新:本包的使用方式已经变了。**
|
||||||
|
>
|
||||||
|
> 它是为「**Gitea + act_runner + 又拍云同步** 整套可移植部署」设计的,
|
||||||
|
> 但 **构建已由 CNB 托管**,所以 **runner 与 upyun-sync 都不需要了**。
|
||||||
|
> Gitea 现在的角色只剩**代码辅仓**(只推不拉、不参与构建)。
|
||||||
|
>
|
||||||
|
> **要迁移 Gitea,请看 [`docs/Gitea迁移指南.md`](../../docs/Gitea迁移指南.md)** ——
|
||||||
|
> 那里有本仓 9 处写死旧地址的完整清单,以及「迁移实际只剩搬数据 + 改地址」的结论。
|
||||||
|
>
|
||||||
|
> 本包现状:**只 `docker compose up -d gitea` 就够了**,下面 compose 里的
|
||||||
|
> `runner` / `upyun-sync` 两段可以忽略。
|
||||||
|
>
|
||||||
|
> 已修正的两个硬伤(2026-10-06):
|
||||||
|
> - `docker-compose.yml` 镜像 tag `1.28.0-rootless` **不存在** → 改为 `28.0.0-rootless`
|
||||||
|
> - `.gitignore` 漏了 `backups/` → 已补(`backup.sh` 产物含 secrets 与完整 data 卷)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
把博客相关的**代码托管(Gitea)+ CI 执行器(act_runner)+ 又拍云同步**打包成一套 docker-compose,
|
把博客相关的**代码托管(Gitea)+ CI 执行器(act_runner)+ 又拍云同步**打包成一套 docker-compose,
|
||||||
目标:**任何一台机器上,复制文件 + 一条命令就能拉起整套环境**,彻底告别「迁移要半天手工操作」。
|
目标:**任何一台机器上,复制文件 + 一条命令就能拉起整套环境**,彻底告别「迁移要半天手工操作」。
|
||||||
@@ -26,7 +26,11 @@ services:
|
|||||||
# 迁移:把旧机器 /opt/gitea/data 整个 rsync 到本机 ./data/gitea 即可
|
# 迁移:把旧机器 /opt/gitea/data 整个 rsync 到本机 ./data/gitea 即可
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
gitea:
|
gitea:
|
||||||
image: gitea/gitea:1.28.0-rootless
|
# ★ 2026-10-06 修正:Gitea 28 起去掉了历史的 `1.` 前缀 ——
|
||||||
|
# 原写的 `1.28.0-rootless` **这个 tag 根本不存在**,`docker compose up` 会卡在第一屏。
|
||||||
|
# 实测(`docker pull`):`28.0.0-rootless` ✅ / `latest` ✅ / `1.28.0-rootless` ❌。
|
||||||
|
# 这里 pin 死版本,避免被 `latest` 悄悄升级。
|
||||||
|
image: gitea/gitea:28.0.0-rootless
|
||||||
container_name: gitea
|
container_name: gitea
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
environment:
|
environment:
|
||||||
File renamed without changes.
File renamed without changes.
@@ -1,5 +1,13 @@
|
|||||||
# 迁移前检查清单(2026-10-04 实测)
|
# 迁移前检查清单(2026-10-04 实测)
|
||||||
|
|
||||||
|
> ⚠️ **本文写于 2026-10-04,部分内容已过时。**
|
||||||
|
> 当时的迁移目标是「把 **Gitea + act_runner + 又拍云同步** 整套搬走」——
|
||||||
|
> **现在构建已由 CNB 托管,runner / upyun-sync / 中转机 都不需要了**,迁移面大幅缩小。
|
||||||
|
>
|
||||||
|
> 👉 **要迁移请看 [`docs/Gitea迁移指南.md`](../../docs/Gitea迁移指南.md)**(现行版本,
|
||||||
|
> 含「本仓 9 处写死旧地址」的完整清单)。
|
||||||
|
> 本文保留的价值:容器网络写法、资源评估、rsync 属主、`ROOT_URL` 那几条仍然成立。
|
||||||
|
|
||||||
> 目标:把境外机 `23.254.236.47` 上的 Gitea + runner 搬到**国内机**(当前中转机
|
> 目标:把境外机 `23.254.236.47` 上的 Gitea + runner 搬到**国内机**(当前中转机
|
||||||
> `119.29.215.187`,Ubuntu 24.04)。
|
> `119.29.215.187`,Ubuntu 24.04)。
|
||||||
> 下面是**照着做完再动手**的清单。带 ★ 的是会**直接卡住迁移**的硬伤。
|
> 下面是**照着做完再动手**的清单。带 ★ 的是会**直接卡住迁移**的硬伤。
|
||||||
@@ -226,7 +226,7 @@ git config --global credential.helper manager # Windows 的 Git Credential Man
|
|||||||
|---|---|---|
|
|---|---|---|
|
||||||
| `write-server/nginx/ssl/privkey.pem` | **真实 TLS 私钥**(EC P-256,`BEGIN PRIVATE KEY`),2026-06-22 起在库 | 已跟踪 |
|
| `write-server/nginx/ssl/privkey.pem` | **真实 TLS 私钥**(EC P-256,`BEGIN PRIVATE KEY`),2026-06-22 起在库 | 已跟踪 |
|
||||||
| `.env` | `SILICONFLOW_API_KEY`、`ZHIPU_API_KEY` | 已跟踪 |
|
| `.env` | `SILICONFLOW_API_KEY`、`ZHIPU_API_KEY` | 已跟踪 |
|
||||||
| `GITEA_SECRETS.md` | Gitea 相关凭据说明 | 已跟踪 |
|
| `docs/GITEA_SECRETS.md` | Gitea 相关凭据说明 | 已跟踪 |
|
||||||
| `content/posts/2024/.../setup-secrets.png` | 疑似密钥配置截图 | 已跟踪 |
|
| `content/posts/2024/.../setup-secrets.png` | 疑似密钥配置截图 | 已跟踪 |
|
||||||
|
|
||||||
**关于暴露面**:该仓一直是**私有**的(匿名 API 返回 404)。2026-10-06 账号被平台标记后
|
**关于暴露面**:该仓一直是**私有**的(匿名 API 返回 404)。2026-10-06 账号被平台标记后
|
||||||
@@ -237,7 +237,7 @@ git config --global credential.helper manager # Windows 的 Git Credential Man
|
|||||||
1. **CNB 仓库保持「私有」** —— 这些文件在私有仓里影响可控
|
1. **CNB 仓库保持「私有」** —— 这些文件在私有仓里影响可控
|
||||||
2. **`git rm --cached` 停止继续跟踪**(历史里的删不掉,但至少不再新增):
|
2. **`git rm --cached` 停止继续跟踪**(历史里的删不掉,但至少不再新增):
|
||||||
```bash
|
```bash
|
||||||
git rm --cached .env GITEA_SECRETS.md write-server/nginx/ssl/privkey.pem write-server/nginx/ssl/fullchain.pem
|
git rm --cached .env docs/GITEA_SECRETS.md write-server/nginx/ssl/privkey.pem write-server/nginx/ssl/fullchain.pem
|
||||||
```
|
```
|
||||||
⚠️ 注意:`.gitignore` 里其实**已经有** `.env` / `.env.*` 规则 —— 它们失效的原因不是规则写错,
|
⚠️ 注意:`.gitignore` 里其实**已经有** `.env` / `.env.*` 规则 —— 它们失效的原因不是规则写错,
|
||||||
而是**忽略规则对「已跟踪」文件无效**,所以必须显式 `git rm --cached`。
|
而是**忽略规则对「已跟踪」文件无效**,所以必须显式 `git rm --cached`。
|
||||||
File renamed without changes.
@@ -0,0 +1,248 @@
|
|||||||
|
# Gitea 迁移指南
|
||||||
|
|
||||||
|
> **什么时候看这篇**:自建 Gitea 要换机器 / 换地址时,**从头照着做**。
|
||||||
|
> 迁移的坑不在「搬数据」,而在**本仓有 9 处地方写死了旧地址**(第三节),漏一处就会在旧机下线那天才报错。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 一、为什么要迁
|
||||||
|
|
||||||
|
| 项 | 现状 |
|
||||||
|
|---|---|
|
||||||
|
| 承载机器 | **境外 VPS `23.254.236.47`**(2 核 / 2 G 内存 / 50 G 磁盘) |
|
||||||
|
| **到期时间** | **2026 年 11 月**(见 `deploy/gitea/README.md` 原始记录) |
|
||||||
|
| 版本 | Gitea **28.0.0**(`/api/v1/version` 实测) |
|
||||||
|
| 实例地址 | `http://23.254.236.47:3001`(HTTP 直连 :3001,**没有走域名/证书**) |
|
||||||
|
| 仓库 | `zqlit/blog`(私有) |
|
||||||
|
| 账号 | `zqlit` |
|
||||||
|
|
||||||
|
**它在架构里的角色**:**代码辅仓** —— 只推不拉、不参与构建、不受第三方平台规则约束。
|
||||||
|
主仓是 CNB(`origin`,推送即触发构建)。
|
||||||
|
|
||||||
|
> 换句话说:**它是备份体系里「在线的那一路」**,不是构建链路的一环。
|
||||||
|
> 这一点决定了迁移比想象中简单得多 —— 见下一节。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 二、★ 迁移范围已经大幅缩小(先读这节,别照旧清单瞎忙)
|
||||||
|
|
||||||
|
仓库里的 [`deploy/gitea/迁移前检查清单.md`](../deploy/gitea/迁移前检查清单.md) 是 **2026-10-04** 写的,
|
||||||
|
当时的目标是「把 **Gitea + act_runner + 又拍云同步** 整套搬到国内机」。
|
||||||
|
**那个前提已经不存在了**:
|
||||||
|
|
||||||
|
| 2026-10-04 的迁移面 | 现在 | 为什么 |
|
||||||
|
|---|---|---|
|
||||||
|
| Gitea 本体 | ✅ **仍要迁** | 唯一的代码辅仓 |
|
||||||
|
| `act_runner`(自建 Actions) | ❌ **不需要** | 构建已由 **CNB** 托管,`.github/` 早已删除 |
|
||||||
|
| `upyun-sync`(又拍云同步容器) | ❌ **不需要** | 又拍云同步已在 CNB 流水线里 |
|
||||||
|
| 广州中转机 | ❌ **不需要** | CNB 构建节点在国内,直连又拍云 |
|
||||||
|
| `cos_sign.py` / COS | ❌ **早已砍掉** | 见归档的 `砍COS改造步骤.md` |
|
||||||
|
|
||||||
|
→ **迁移实际只剩一件事:把 Gitea 的数据卷搬到新机器,再把 9 处地址改掉。**
|
||||||
|
|
||||||
|
`deploy/gitea/docker-compose.yml` 里那一大坨 `runner` / `upyun-sync` 服务定义,
|
||||||
|
**迁移时不必启动**(可以直接注释掉,或干脆不管 —— 只 `up -d gitea` 即可)。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 三、★★ 必须同步修改的位置(漏一处 = 旧机下线后才报错)
|
||||||
|
|
||||||
|
按「易漏程度」排序。**第 4、5 项是最容易漏的**,因为它们在线上机器上,不在本仓库里。
|
||||||
|
|
||||||
|
| # | 位置 | 改成 | 漏掉的后果 |
|
||||||
|
|---|---|---|---|
|
||||||
|
| 1 | **本机** `.git/config` 的 `gitea` remote | 新地址 | `git pushall` 推不动辅仓 |
|
||||||
|
| 2 | `scripts/setup-cnb-remotes.sh` 里的 `GITEA_URL` 默认值 | 新地址 | 重跑脚本时把远端**指回旧机** |
|
||||||
|
| 3 | `deploy/editor-api/bootstrap.sh` 里的 `GITEA_URL` 默认值 | 新地址 | 新部署的容器指向旧机 |
|
||||||
|
| 4 | ★ **线上国内机 `/srv/editor-api/.env`** 的 `GITEA_URL` | 新地址 | 写作后台发文章时辅仓推送**持续报错**(主仓成功、只警告,**不会有人发现**) |
|
||||||
|
| 5 | ★ **线上国内机 `/srv/blog`** 的 `gitea` remote | 新地址 | 同上 |
|
||||||
|
| 6 | `docs/GITEA_SECRETS.md` | 地址 + 凭据 | 后人照文档操作时指向旧机 |
|
||||||
|
| 7 | `架构总览.md`(§1.2 地址地图 / §2 旅程图 / §5.2 远端表 / §6 待办 #7) | 新地址 | 文档失真 |
|
||||||
|
| 8 | `README.md`(发布流程图 + 推送说明 + 脚本表) | 新地址 | 文档失真 |
|
||||||
|
| 9 | `editor-api/README.md`(辅仓那一行)、`scripts/backup-run.mjs`(头部注释) | 新地址 | 文档失真 |
|
||||||
|
|
||||||
|
**不用改的**(它们只引用 remote 名字 `gitea`,不含地址):
|
||||||
|
`docker-compose.editor.yml`(`PUSH_REMOTES: origin,gitea`)、`editor-api/server.mjs`、
|
||||||
|
`pushall` 别名本身。
|
||||||
|
|
||||||
|
### 一条命令改本机那两处(1 + 2)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd /e/GitHub/blog
|
||||||
|
|
||||||
|
# 1) 本机 remote —— 换 GITEA_URL 即可,凭据会自动拼进去
|
||||||
|
GITEA_URL='http://<新机IP>:3001/zqlit/blog.git' \
|
||||||
|
GITEA_PASS='<Gitea 密码或访问令牌>' \
|
||||||
|
bash scripts/setup-cnb-remotes.sh https://cnb.cool/zqlit/blog
|
||||||
|
|
||||||
|
# 验证:两个远端都在、地址是新的
|
||||||
|
git remote -v | sed -E 's#://[^@]*@#://***@#'
|
||||||
|
```
|
||||||
|
|
||||||
|
### 线上国内机那两处(4 + 5)
|
||||||
|
|
||||||
|
国内机没有 SSH,走 1Panel API 执行(本机 `python .editor-tmp/cnrun.py <脚本>`):
|
||||||
|
|
||||||
|
```bash
|
||||||
|
set -uo pipefail
|
||||||
|
NEW='http://<新机IP>:3001/zqlit/blog.git'
|
||||||
|
PASS='<Gitea 密码或访问令牌>'
|
||||||
|
|
||||||
|
# ① .env —— 改 GITEA_URL(GITEA_PASS 不变的话不用动)
|
||||||
|
sed -i "s#^GITEA_URL=.*#GITEA_URL=$NEW#" /srv/editor-api/.env
|
||||||
|
|
||||||
|
# ② /srv/blog 的 remote
|
||||||
|
git -C /srv/blog remote remove gitea
|
||||||
|
git -C /srv/blog remote add gitea "$(printf '%s' "$NEW" | sed -E "s#^(https?://)#\1zqlit:${PASS}@#")"
|
||||||
|
|
||||||
|
# ③ 重建容器(容器启动时读 .env)
|
||||||
|
cd /srv/editor-api && docker compose up -d --build
|
||||||
|
|
||||||
|
# ④ 验证
|
||||||
|
docker exec editor-api sh -c 'cd /srv/blog && git remote -v' | sed -E 's#://[^@]*@#://***@#'
|
||||||
|
curl -s http://127.0.0.1:8017/health; echo # remotes 应为 ["origin","gitea"]
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 四、建议:新实例用域名,不要再用 IP
|
||||||
|
|
||||||
|
现在写死的是 `23.254.236.47:3001` —— **IP 一换,上面 9 处全部要改**。
|
||||||
|
如果新实例挂个域名(如 `gitea.usj.cc`,DNS 指向新机),以后再搬机器**只改 DNS**,上面 9 处全都不用动。
|
||||||
|
|
||||||
|
> ⚠️ **Gitea 28 起不再读 `[server] DOMAIN`** —— 实例域名(含默认 SSH 域名)全部来自 **`ROOT_URL`**。
|
||||||
|
> 改域名时**只改 `ROOT_URL`** 一处。(`deploy/gitea/docker-compose.yml` 里两个都填了,所以现在的配置没问题。)
|
||||||
|
|
||||||
|
换域名的额外成本:要在 1Panel 的 OpenResty 里加一个反代站点 → `127.0.0.1:3001`,并配证书。
|
||||||
|
(目标机 80/443 已被 1Panel 的 OpenResty 占用,Gitea 容器映射的是宿主 `3001`/`2222`。)
|
||||||
|
|
||||||
|
**权衡**:花一次配置,换掉以后每一次迁移都要改 9 处的麻烦。**推荐做。**
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 五、迁数据
|
||||||
|
|
||||||
|
### 5.1 迁移前的硬伤检查(已修,确认一下即可)
|
||||||
|
|
||||||
|
| 项 | 状态 |
|
||||||
|
|---|---|
|
||||||
|
| `docker-compose.yml` 镜像 tag | ✅ **已修**(2026-10-06):原来是 `gitea/gitea:1.28.0-rootless` —— **这个 tag 不存在**,Gitea 28 起去掉了 `1.` 前缀。现为 `28.0.0-rootless`(pin 死版本,别用 `latest`) |
|
||||||
|
| `deploy/gitea/.gitignore` 缺 `backups/` | ✅ **已补**:跑一次 `backup.sh` 会在 `backups/` 落 `gitea-dump-*.zip`(含 secrets)与完整 data 卷,原先漏忽略,`git add .` 一下就进历史 |
|
||||||
|
|
||||||
|
### 5.2 数据怎么搬 —— **用 rsync,不用 dump**
|
||||||
|
|
||||||
|
| 方式 | 适用 | 说明 |
|
||||||
|
|---|---|---|
|
||||||
|
| **rsync 数据卷**(推荐) | 同架构迁移 | 保完整(含仓库、app.ini、头像、LFS)。**用 `rsync -a` 保留属主** |
|
||||||
|
| `gitea dump` | 跨版本 / 跨数据库 | `deploy/gitea/scripts/backup.sh` 已封装;适合做归档,不适合日常迁移 |
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 旧机 → 新机(在新机上执行,或先把 data 卷打包传过去)
|
||||||
|
rsync -av --progress root@23.254.236.47:/opt/gitea/data/ /srv/gitea/data/gitea/
|
||||||
|
```
|
||||||
|
|
||||||
|
> ⚠️ **属主必须是 uid/gid 1000** —— Gitea rootless 镜像按 1000 跑,属主不对容器起不来。
|
||||||
|
> `rsync -a` 会保留;如果中间过了 Windows 或换了 uid,事后要 `chown -R 1000:1000`。
|
||||||
|
|
||||||
|
> ⚠️ **新版本必须 ≥ 旧版本**(现在是 28.0.0)。把数据从新版本搬到旧版本会出兼容问题。
|
||||||
|
|
||||||
|
### 5.3 启动
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd deploy/gitea
|
||||||
|
cp .env.example .env # 填 GITEA_DOMAIN / GITEA_ROOT_URL(用域名的话)
|
||||||
|
mkdir -p data/gitea
|
||||||
|
docker compose up -d gitea # 只起 gitea,runner/upyun-sync 不需要
|
||||||
|
docker compose ps
|
||||||
|
```
|
||||||
|
|
||||||
|
> `deploy/gitea/docker-compose.yml` 里还留着 `runner` / `upyun-sync` 两个服务定义 ——
|
||||||
|
> 那是 2026-10-04 的形态,**现在不需要**(构建已交给 CNB)。只 `up -d gitea` 即可,
|
||||||
|
> 或在迁移时顺手把这两段注释掉。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 六、切换顺序(关键:**别让辅仓出现空窗**)
|
||||||
|
|
||||||
|
辅仓的价值在于「主仓出问题时它那儿还有」。所以顺序是 **先建好新的、验证通过、再拆旧的**:
|
||||||
|
|
||||||
|
```
|
||||||
|
1. 新机起 Gitea,数据已就位,验证能 clone
|
||||||
|
2. 本机配好新 remote(第三节 1、2 项)
|
||||||
|
3. 从本机推一次,确认新实例能收到 ← 新的已经可用
|
||||||
|
4. 改线上国内机(第三节 4、5 项),重建容器,实测双推 ← 两条推送入口都切过来了
|
||||||
|
5. 观察一天:`git pushall` 与后台发文章,都确认辅仓同步正常
|
||||||
|
6. 旧机下线(等到期即可,不必急) ← 旧的才拆
|
||||||
|
```
|
||||||
|
|
||||||
|
**不要在 3、4 步之前就把旧机停掉** —— 那会出现「新的还没验证、旧的已经没了」。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 七、验证清单
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# ① 本机:两个远端都是新地址
|
||||||
|
git remote -v | sed -E 's#://[^@]*@#://***@#'
|
||||||
|
|
||||||
|
# ② 本机实测双推(推临时分支 → 确认 SHA → 删除)
|
||||||
|
git pushall
|
||||||
|
git push gitea HEAD:refs/heads/tmp-migrate-test
|
||||||
|
git ls-remote gitea refs/heads/tmp-migrate-test # 应回新实例的 SHA
|
||||||
|
git push gitea --delete refs/heads/tmp-migrate-test
|
||||||
|
git ls-remote gitea refs/heads/tmp-migrate-test # 应为空
|
||||||
|
|
||||||
|
# ③ 三处 main 对齐
|
||||||
|
echo "local = $(git rev-parse HEAD)"
|
||||||
|
echo "origin = $(git ls-remote origin refs/heads/main | cut -f1)"
|
||||||
|
echo "gitea = $(git ls-remote gitea refs/heads/main | cut -f1)"
|
||||||
|
|
||||||
|
# ④ 历史完整性:新实例上的提交数应与本地一致
|
||||||
|
git ls-remote gitea refs/heads/main
|
||||||
|
git rev-list --count HEAD
|
||||||
|
|
||||||
|
# ⑤ 线上容器(国内机执行)
|
||||||
|
curl -s http://127.0.0.1:8017/health # "remotes":["origin","gitea"]
|
||||||
|
docker exec editor-api sh -c 'cd /srv/blog && GIT_TERMINAL_PROMPT=0 git push gitea --dry-run'
|
||||||
|
```
|
||||||
|
|
||||||
|
> ★ **最后一条特别重要**:`editor-api/src/git.mjs` 对辅仓失败是**只警告不阻断**的 ——
|
||||||
|
> 辅仓悄悄推不上去,发布照样报成功。所以**必须主动 `--dry-run` 验一次**,别等要用备份时才发现。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 八、回滚
|
||||||
|
|
||||||
|
迁移全程是**加法**(新实例起来 → 改地址 → 推一次),旧实例在最后一步之前一直没动:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 回滚本机 remote
|
||||||
|
GITEA_URL='http://23.254.236.47:3001/zqlit/blog.git' \
|
||||||
|
GITEA_PASS='<旧密码>' bash scripts/setup-cnb-remotes.sh https://cnb.cool/zqlit/blog
|
||||||
|
|
||||||
|
# 回滚线上国内机 .env(把 GITEA_URL 改回去)+ docker compose up -d --build
|
||||||
|
```
|
||||||
|
|
||||||
|
**只要没停旧机,回滚就是把地址改回去。**
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 九、★ 迁移前先决定:这个辅仓还要不要留
|
||||||
|
|
||||||
|
用户提过「感觉架构还是复杂了」。Gitea 是当前**唯一需要你自己运维的常驻服务**(2 核 2 G 境外机),
|
||||||
|
而它**不参与构建、不参与发布** —— 纯粹是备份体系里「在线的那一路」。
|
||||||
|
|
||||||
|
| 选项 | 换来什么 | 代价 |
|
||||||
|
|---|---|---|
|
||||||
|
| **A. 迁到新机**(本文档前面全部内容) | 保留「可 clone、可按提交追溯、不受平台规则约束」的在线副本 | 继续养一台机器 + 一处需要运维的实例 |
|
||||||
|
| **B. 不迁,去掉辅仓** | 少一台机器、少一个要运维的部件;架构回到「CNB 主仓 + F50 离线加密 bundle」两层 | 少一层在线冗余。离线层仍是**完整历史**(`git bundle --all`),且备份已带失败告警 |
|
||||||
|
| **C. 换成托管平台的私有仓** | 不用自己运维 | CNB 已是托管平台,再挂一家性质相同的,收益有限(见归档的 `平台与选型/` 系列) |
|
||||||
|
|
||||||
|
**判断依据**:Gitea 现在挡的是什么?——「CNB 跟 GitHub 一样出问题」。
|
||||||
|
但离线 bundle 已经覆盖了这个场景(且加密、带告警、每天自动跑)。
|
||||||
|
Gitea 多出来的独有价值只有两点:**在线可浏览**、**可增量拉取**(不用等一天一次的备份)。
|
||||||
|
如果这两点你用不上,**选项 B 是合理的简化**。
|
||||||
|
|
||||||
|
> 若选 B:把 `deploy/gitea/` 保留在仓库里即可(迁移清单和部署包留着,随时能重建),
|
||||||
|
> 然后参考本文档第三节,把那 9 处的 `gitea` 相关引用一并清掉
|
||||||
|
> —— 别忘了 **第 4、5 项**(线上那两处),否则容器会一直对着一个已经没了的辅仓报错。
|
||||||
@@ -0,0 +1,68 @@
|
|||||||
|
# 文档地图
|
||||||
|
|
||||||
|
仓库的文档分三层,**看文档先看这张表**:
|
||||||
|
|
||||||
|
| 层 | 位置 | 什么时候看 |
|
||||||
|
|---|---|---|
|
||||||
|
| **入口** | [`../README.md`](../README.md)、[`../架构总览.md`](../架构总览.md) | 想搞清「这个项目是什么、现在长什么样」 |
|
||||||
|
| **当前有效** | 本目录(`docs/*.md`) | 要动某块东西,先看对应的专题文档 |
|
||||||
|
| **历史归档** | [`archive/`](archive/) | 想知道「当初为什么这么选」——**不代表现状** |
|
||||||
|
|
||||||
|
> ⚠️ 归档文档开头都有 `📦 本文档已归档` 标记。里面出现的一切结论,**先去 `架构总览.md` 复核再用**。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 一、当前有效
|
||||||
|
|
||||||
|
| 文档 | 内容 | 什么时候更新 |
|
||||||
|
|---|---|---|
|
||||||
|
| [`证书管家.md`](证书管家.md) | **证书子系统唯一事实源**:现状速览、架构定案(签发在国内机 / Worker 只读)、决策沿革与**勿回退的坑**(§8.4 / §9.9 / §9.11 / §9.12) | 改签发/部署代码前 |
|
||||||
|
| [`Gitea迁移指南.md`](Gitea迁移指南.md) | 自建 Gitea 要搬机器时,**必须同步改的全部位置** + 数据迁移 + 验证清单 | 迁移 Gitea 时**从头照着做** |
|
||||||
|
| [`架构精简候选.md`](架构精简候选.md) | **待决策清单**:复杂度盘点 + 5 个可精简候选(收益/代价/风险/怎么做)+ 建议执行顺序 | 想「让架构简单点」时看 |
|
||||||
|
| [`CNB构建落地方案.md`](CNB构建落地方案.md) | 迁 CNB 的实施方案、流水线细节与实测数据 | 改 `.cnb.yml` / `deploy/Dockerfile` 前 |
|
||||||
|
| [`GITEA_SECRETS.md`](GITEA_SECRETS.md) | Gitea 相关凭据清单 —— ⚠️ **含明文凭据,勿外传** | 凭据轮换后 |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 二、历史归档(`archive/`)
|
||||||
|
|
||||||
|
### 平台与选型 —— 「当初为什么选它 / 没选它」
|
||||||
|
|
||||||
|
| 文档 | 结论(一句话) |
|
||||||
|
|---|---|
|
||||||
|
| [`代码源与构建平台选型.md`](archive/平台与选型/代码源与构建平台选型.md) | CNB / Gitee / GitLab / EdgeOne / ESA 横向对比 → **选 CNB** |
|
||||||
|
| [`Gitee方案评估.md`](archive/平台与选型/Gitee方案评估.md) | Gitee 卡单文件 50MB / 单仓 500MB → **未采用** |
|
||||||
|
| [`EdgeOne双区域方案评估.md`](archive/平台与选型/EdgeOne双区域方案评估.md) | 境内外双线路方案 → 现用于境外线路 |
|
||||||
|
| [`阿里云ESA评估.md`](archive/平台与选型/阿里云ESA评估.md) | 与 EdgeOne 对比 → **未采用** |
|
||||||
|
| [`精简方案-只留CF和Hugo.md`](archive/平台与选型/精简方案-只留CF和Hugo.md) | 大精简的设想与边界 |
|
||||||
|
| [`砍COS改造步骤.md`](archive/平台与选型/砍COS改造步骤.md) | 腾讯云 COS 下线记录(**已执行完毕**) |
|
||||||
|
|
||||||
|
### 功能与修复 —— 已完结的一次性改造
|
||||||
|
|
||||||
|
| 文档 | 内容 |
|
||||||
|
|---|---|
|
||||||
|
| [`诊断报告-2026-10-06.md`](archive/功能与修复/诊断报告-2026-10-06.md) | 四问诊断(当天的体检报告) |
|
||||||
|
| [`评论孤儿修复方案-2026-10-06.md`](archive/功能与修复/评论孤儿修复方案-2026-10-06.md) | 找回挂在 404 页面上的评论 |
|
||||||
|
| [`评论加载优化方案.md`](archive/功能与修复/评论加载优化方案.md) | 评论区加载性能(CF 免费版约束下) |
|
||||||
|
| [`在线编辑器集成评估.md`](archive/功能与修复/在线编辑器集成评估.md) | 在线编辑器集成到后台的评估 → **已实现**(见 `editor-api/`) |
|
||||||
|
|
||||||
|
### 主题与内容 —— Hugo 主题 / 字体 / 样式
|
||||||
|
|
||||||
|
| 文档 | 内容 |
|
||||||
|
|---|---|
|
||||||
|
| [`主题与内容/性能优化(历史)/`](archive/主题与内容/性能优化(历史)/) | 2025 年那轮主题性能优化(18 篇,含 PJAX / JS 按需加载 / 字体子集化)。⚠️ 其中「GitHub Actions」两篇已彻底失效 —— GitHub 已退出本项目 |
|
||||||
|
| [`主题与内容/古风官职字符添加指南.md`](archive/主题与内容/古风官职字符添加指南.md) | 字体子集增补生僻字的**操作步骤**(配套 `scripts/add_ancient_chars.py`,现在仍可用) |
|
||||||
|
| [`主题与内容/博客字体优化文章规划.md`](archive/主题与内容/博客字体优化文章规划.md) | 字体优化系列文章的选题规划 |
|
||||||
|
| [`主题与内容/深色模式表格修复指南.md`](archive/主题与内容/深色模式表格修复指南.md) | 深色模式表格样式问题定位与修复 |
|
||||||
|
| [`主题与内容/CLEANUP_GUIDE.md`](archive/主题与内容/CLEANUP_GUIDE.md) | Ying 主题自带文档的清理清单(**已执行**) |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 三、还有哪些文档不在本表里
|
||||||
|
|
||||||
|
| 位置 | 说明 |
|
||||||
|
|---|---|
|
||||||
|
| `blog-admin/README.md`、`blog-admin/部署清单.md` | 评论后端(artalk-cf)的完整说明,**随子系统走** |
|
||||||
|
| `editor-api/README.md` | 写作后台 API(国内机容器),含「落盘:写一次,存三处」 |
|
||||||
|
| `write-server/`、`write/` 内的文档 | 各自子系统的说明 |
|
||||||
|
| `.workbuddy/memory/` | 逐日工作日志与项目长期记忆(**不入库**,仅供本地 agent 使用) |
|
||||||
@@ -1,3 +1,6 @@
|
|||||||
|
> 📦 **本文档已归档**(2026-10-06)。它记录的是**当时的工作过程与结论**,可能已被后续决策推翻。
|
||||||
|
> **请勿据此判断当前架构** —— 现行架构唯一事实源是 [`架构总览.md`](../../../架构总览.md)。
|
||||||
|
|
||||||
# 🧹 Ying主题文档清理指南
|
# 🧹 Ying主题文档清理指南
|
||||||
|
|
||||||
## 📋 需要删除的文件(20个)
|
## 📋 需要删除的文件(20个)
|
||||||
@@ -1,3 +1,6 @@
|
|||||||
|
> 📦 **本文档已归档**(2026-10-06)。它记录的是**当时的工作过程与结论**,可能已被后续决策推翻。
|
||||||
|
> **请勿据此判断当前架构** —— 现行架构唯一事实源是 [`架构总览.md`](../../../架构总览.md)。
|
||||||
|
|
||||||
# 博客字体优化方案 - 文章规划
|
# 博客字体优化方案 - 文章规划
|
||||||
|
|
||||||
## 📋 文章定位
|
## 📋 文章定位
|
||||||
@@ -1,3 +1,6 @@
|
|||||||
|
> 📦 **本文档已归档**(2026-10-06)。它记录的是**当时的工作过程与结论**,可能已被后续决策推翻。
|
||||||
|
> **请勿据此判断当前架构** —— 现行架构唯一事实源是 [`架构总览.md`](../../../架构总览.md)。
|
||||||
|
|
||||||
# 📜 添加古风官职字符到字体子集
|
# 📜 添加古风官职字符到字体子集
|
||||||
|
|
||||||
## 📋 需要添加的字符
|
## 📋 需要添加的字符
|
||||||
@@ -1,3 +1,6 @@
|
|||||||
|
> 📦 **本文档已归档**(2026-10-06)。它记录的是**当时的工作过程与结论**,可能已被后续决策推翻。
|
||||||
|
> **请勿据此判断当前架构** —— 现行架构唯一事实源是 [`架构总览.md`](../../../../架构总览.md)。
|
||||||
|
|
||||||
# 01-项目完成总结
|
# 01-项目完成总结
|
||||||
|
|
||||||
**创建日期:** 2026-06-03
|
**创建日期:** 2026-06-03
|
||||||
@@ -1,3 +1,6 @@
|
|||||||
|
> 📦 **本文档已归档**(2026-10-06)。它记录的是**当时的工作过程与结论**,可能已被后续决策推翻。
|
||||||
|
> **请勿据此判断当前架构** —— 现行架构唯一事实源是 [`架构总览.md`](../../../../架构总览.md)。
|
||||||
|
|
||||||
# 02-方案1完成总结
|
# 02-方案1完成总结
|
||||||
|
|
||||||
**创建日期:** 2026-06-03
|
**创建日期:** 2026-06-03
|
||||||
@@ -1,3 +1,6 @@
|
|||||||
|
> 📦 **本文档已归档**(2026-10-06)。它记录的是**当时的工作过程与结论**,可能已被后续决策推翻。
|
||||||
|
> **请勿据此判断当前架构** —— 现行架构唯一事实源是 [`架构总览.md`](../../../../架构总览.md)。
|
||||||
|
|
||||||
# 03-三步优化完整指南
|
# 03-三步优化完整指南
|
||||||
|
|
||||||
**创建日期:** 2026-06-03
|
**创建日期:** 2026-06-03
|
||||||
@@ -1,3 +1,6 @@
|
|||||||
|
> 📦 **本文档已归档**(2026-10-06)。它记录的是**当时的工作过程与结论**,可能已被后续决策推翻。
|
||||||
|
> **请勿据此判断当前架构** —— 现行架构唯一事实源是 [`架构总览.md`](../../../../架构总览.md)。
|
||||||
|
|
||||||
# 04-JS按需加载优化
|
# 04-JS按需加载优化
|
||||||
|
|
||||||
**创建日期:** 2026-06-03
|
**创建日期:** 2026-06-03
|
||||||
@@ -1,3 +1,6 @@
|
|||||||
|
> 📦 **本文档已归档**(2026-10-06)。它记录的是**当时的工作过程与结论**,可能已被后续决策推翻。
|
||||||
|
> **请勿据此判断当前架构** —— 现行架构唯一事实源是 [`架构总览.md`](../../../../架构总览.md)。
|
||||||
|
|
||||||
# 05-PJAX适配说明
|
# 05-PJAX适配说明
|
||||||
|
|
||||||
**创建日期:** 2026-06-03
|
**创建日期:** 2026-06-03
|
||||||
@@ -1,3 +1,6 @@
|
|||||||
|
> 📦 **本文档已归档**(2026-10-06)。它记录的是**当时的工作过程与结论**,可能已被后续决策推翻。
|
||||||
|
> **请勿据此判断当前架构** —— 现行架构唯一事实源是 [`架构总览.md`](../../../../架构总览.md)。
|
||||||
|
|
||||||
# 06-PJAX修复总结
|
# 06-PJAX修复总结
|
||||||
|
|
||||||
**创建日期:** 2026-06-03
|
**创建日期:** 2026-06-03
|
||||||
@@ -1,3 +1,6 @@
|
|||||||
|
> 📦 **本文档已归档**(2026-10-06)。它记录的是**当时的工作过程与结论**,可能已被后续决策推翻。
|
||||||
|
> **请勿据此判断当前架构** —— 现行架构唯一事实源是 [`架构总览.md`](../../../../架构总览.md)。
|
||||||
|
|
||||||
# 07-字体子集化优化
|
# 07-字体子集化优化
|
||||||
|
|
||||||
**创建日期:** 2026-06-03
|
**创建日期:** 2026-06-03
|
||||||
+3
@@ -1,3 +1,6 @@
|
|||||||
|
> 📦 **本文档已归档**(2026-10-06)。它记录的是**当时的工作过程与结论**,可能已被后续决策推翻。
|
||||||
|
> **请勿据此判断当前架构** —— 现行架构唯一事实源是 [`架构总览.md`](../../../../架构总览.md)。
|
||||||
|
|
||||||
# 08-GitHub-Actions使用指南
|
# 08-GitHub-Actions使用指南
|
||||||
|
|
||||||
**创建日期:** 2026-06-03
|
**创建日期:** 2026-06-03
|
||||||
@@ -1,3 +1,6 @@
|
|||||||
|
> 📦 **本文档已归档**(2026-10-06)。它记录的是**当时的工作过程与结论**,可能已被后续决策推翻。
|
||||||
|
> **请勿据此判断当前架构** —— 现行架构唯一事实源是 [`架构总览.md`](../../../../架构总览.md)。
|
||||||
|
|
||||||
# 09-Actions修复指南
|
# 09-Actions修复指南
|
||||||
|
|
||||||
**创建日期:** 2026-06-03
|
**创建日期:** 2026-06-03
|
||||||
@@ -1,3 +1,6 @@
|
|||||||
|
> 📦 **本文档已归档**(2026-10-06)。它记录的是**当时的工作过程与结论**,可能已被后续决策推翻。
|
||||||
|
> **请勿据此判断当前架构** —— 现行架构唯一事实源是 [`架构总览.md`](../../../../架构总览.md)。
|
||||||
|
|
||||||
# 10-提交指南
|
# 10-提交指南
|
||||||
|
|
||||||
**创建日期:** 2026-06-03
|
**创建日期:** 2026-06-03
|
||||||
@@ -1,3 +1,6 @@
|
|||||||
|
> 📦 **本文档已归档**(2026-10-06)。它记录的是**当时的工作过程与结论**,可能已被后续决策推翻。
|
||||||
|
> **请勿据此判断当前架构** —— 现行架构唯一事实源是 [`架构总览.md`](../../../../架构总览.md)。
|
||||||
|
|
||||||
# 11-JS优化测试指南
|
# 11-JS优化测试指南
|
||||||
|
|
||||||
**创建日期:** 2026-06-03
|
**创建日期:** 2026-06-03
|
||||||
@@ -1,3 +1,6 @@
|
|||||||
|
> 📦 **本文档已归档**(2026-10-06)。它记录的是**当时的工作过程与结论**,可能已被后续决策推翻。
|
||||||
|
> **请勿据此判断当前架构** —— 现行架构唯一事实源是 [`架构总览.md`](../../../../架构总览.md)。
|
||||||
|
|
||||||
# 12-字体优化测试指南
|
# 12-字体优化测试指南
|
||||||
|
|
||||||
**创建日期:** 2026-06-03
|
**创建日期:** 2026-06-03
|
||||||
@@ -1,3 +1,6 @@
|
|||||||
|
> 📦 **本文档已归档**(2026-10-06)。它记录的是**当时的工作过程与结论**,可能已被后续决策推翻。
|
||||||
|
> **请勿据此判断当前架构** —— 现行架构唯一事实源是 [`架构总览.md`](../../../../架构总览.md)。
|
||||||
|
|
||||||
# 13-主题全面优化分析
|
# 13-主题全面优化分析
|
||||||
|
|
||||||
**创建日期:** 2026-06-03
|
**创建日期:** 2026-06-03
|
||||||
@@ -1,3 +1,6 @@
|
|||||||
|
> 📦 **本文档已归档**(2026-10-06)。它记录的是**当时的工作过程与结论**,可能已被后续决策推翻。
|
||||||
|
> **请勿据此判断当前架构** —— 现行架构唯一事实源是 [`架构总览.md`](../../../../架构总览.md)。
|
||||||
|
|
||||||
# 14-JS优化最终方案
|
# 14-JS优化最终方案
|
||||||
|
|
||||||
**创建日期:** 2026-06-03
|
**创建日期:** 2026-06-03
|
||||||
@@ -1,3 +1,6 @@
|
|||||||
|
> 📦 **本文档已归档**(2026-10-06)。它记录的是**当时的工作过程与结论**,可能已被后续决策推翻。
|
||||||
|
> **请勿据此判断当前架构** —— 现行架构唯一事实源是 [`架构总览.md`](../../../../架构总览.md)。
|
||||||
|
|
||||||
# 15-字体优化手动指南
|
# 15-字体优化手动指南
|
||||||
|
|
||||||
**创建日期:** 2026-06-03
|
**创建日期:** 2026-06-03
|
||||||
@@ -1,3 +1,6 @@
|
|||||||
|
> 📦 **本文档已归档**(2026-10-06)。它记录的是**当时的工作过程与结论**,可能已被后续决策推翻。
|
||||||
|
> **请勿据此判断当前架构** —— 现行架构唯一事实源是 [`架构总览.md`](../../../../架构总览.md)。
|
||||||
|
|
||||||
# 16-实施总结报告
|
# 16-实施总结报告
|
||||||
|
|
||||||
**创建日期:** 2026-06-03
|
**创建日期:** 2026-06-03
|
||||||
@@ -1,3 +1,6 @@
|
|||||||
|
> 📦 **本文档已归档**(2026-10-06)。它记录的是**当时的工作过程与结论**,可能已被后续决策推翻。
|
||||||
|
> **请勿据此判断当前架构** —— 现行架构唯一事实源是 [`架构总览.md`](../../../../架构总览.md)。
|
||||||
|
|
||||||
# Ying主题 Markdown 表格样式使用指南
|
# Ying主题 Markdown 表格样式使用指南
|
||||||
|
|
||||||
**创建日期:** 2026-06-03
|
**创建日期:** 2026-06-03
|
||||||
@@ -1,3 +1,6 @@
|
|||||||
|
> 📦 **本文档已归档**(2026-10-06)。它记录的是**当时的工作过程与结论**,可能已被后续决策推翻。
|
||||||
|
> **请勿据此判断当前架构** —— 现行架构唯一事实源是 [`架构总览.md`](../../../../架构总览.md)。
|
||||||
|
|
||||||
# 📚 性能优化文档索引
|
# 📚 性能优化文档索引
|
||||||
|
|
||||||
**整理日期:** 2026-06-03
|
**整理日期:** 2026-06-03
|
||||||
@@ -1,3 +1,6 @@
|
|||||||
|
> 📦 **本文档已归档**(2026-10-06)。它记录的是**当时的工作过程与结论**,可能已被后续决策推翻。
|
||||||
|
> **请勿据此判断当前架构** —— 现行架构唯一事实源是 [`架构总览.md`](../../../架构总览.md)。
|
||||||
|
|
||||||
# 深色模式表格样式修复指南
|
# 深色模式表格样式修复指南
|
||||||
|
|
||||||
## 🔍 问题诊断
|
## 🔍 问题诊断
|
||||||
@@ -1,3 +1,6 @@
|
|||||||
|
> 📦 **本文档已归档**(2026-10-06)。它记录的是**当时的评估与方案**,其中的结论可能已被后续决策推翻。
|
||||||
|
> **请勿据此判断当前架构** —— 现行架构唯一事实源是 [`架构总览.md`](../../../架构总览.md)。
|
||||||
|
|
||||||
# 在线编辑文章 · 集成到 api.200181.xyz/admin
|
# 在线编辑文章 · 集成到 api.200181.xyz/admin
|
||||||
|
|
||||||
> 日期:2026-10-04(定稿)
|
> 日期:2026-10-04(定稿)
|
||||||
@@ -1,3 +1,6 @@
|
|||||||
|
> 📦 **本文档已归档**(2026-10-06)。它记录的是**当时的评估与方案**,其中的结论可能已被后续决策推翻。
|
||||||
|
> **请勿据此判断当前架构** —— 现行架构唯一事实源是 [`架构总览.md`](../../../架构总览.md)。
|
||||||
|
|
||||||
# 评论加载优化方案(Cloudflare 免费版)
|
# 评论加载优化方案(Cloudflare 免费版)
|
||||||
|
|
||||||
> 起因:读者侧「评论加载太慢」。
|
> 起因:读者侧「评论加载太慢」。
|
||||||
@@ -1,3 +1,6 @@
|
|||||||
|
> 📦 **本文档已归档**(2026-10-06)。它记录的是**当时的评估与方案**,其中的结论可能已被后续决策推翻。
|
||||||
|
> **请勿据此判断当前架构** —— 现行架构唯一事实源是 [`架构总览.md`](../../../架构总览.md)。
|
||||||
|
|
||||||
# 评论区孤儿评论修复方案(2026-10-06)
|
# 评论区孤儿评论修复方案(2026-10-06)
|
||||||
|
|
||||||
> ## ✅ 状态:**已执行完成**(2026-10-06 12:2x)
|
> ## ✅ 状态:**已执行完成**(2026-10-06 12:2x)
|
||||||
@@ -1,3 +1,6 @@
|
|||||||
|
> 📦 **本文档已归档**(2026-10-06)。它记录的是**当时的评估与方案**,其中的结论可能已被后续决策推翻。
|
||||||
|
> **请勿据此判断当前架构** —— 现行架构唯一事实源是 [`架构总览.md`](../../../架构总览.md)。
|
||||||
|
|
||||||
# 四问诊断报告(2026-10-06)
|
# 四问诊断报告(2026-10-06)
|
||||||
|
|
||||||
一次性回答四个问题:CDN 刷新、KV 配额、D1 评论对账、certimate 迁移。
|
一次性回答四个问题:CDN 刷新、KV 配额、D1 评论对账、certimate 迁移。
|
||||||
@@ -1,3 +1,6 @@
|
|||||||
|
> 📦 **本文档已归档**(2026-10-06)。它记录的是**当时的评估与方案**,其中的结论可能已被后续决策推翻。
|
||||||
|
> **请勿据此判断当前架构** —— 现行架构唯一事实源是 [`架构总览.md`](../../../架构总览.md)。
|
||||||
|
|
||||||
# EdgeOne 双区域方案评估
|
# EdgeOne 双区域方案评估
|
||||||
|
|
||||||
> 2026-10-04 · 针对「境外用 EdgeOne 国际站、境内改用 EdgeOne 国内站」的构想
|
> 2026-10-04 · 针对「境外用 EdgeOne 国际站、境内改用 EdgeOne 国内站」的构想
|
||||||
@@ -1,3 +1,6 @@
|
|||||||
|
> 📦 **本文档已归档**(2026-10-06)。它记录的是**当时的评估与方案**,其中的结论可能已被后续决策推翻。
|
||||||
|
> **请勿据此判断当前架构** —— 现行架构唯一事实源是 [`架构总览.md`](../../../架构总览.md)。
|
||||||
|
|
||||||
# Gitee 方案评估
|
# Gitee 方案评估
|
||||||
|
|
||||||
> 回答:**「Gitee 算不算一个替代方案?」**
|
> 回答:**「Gitee 算不算一个替代方案?」**
|
||||||
@@ -1,3 +1,6 @@
|
|||||||
|
> 📦 **本文档已归档**(2026-10-06)。它记录的是**当时的评估与方案**,其中的结论可能已被后续决策推翻。
|
||||||
|
> **请勿据此判断当前架构** —— 现行架构唯一事实源是 [`架构总览.md`](../../../架构总览.md)。
|
||||||
|
|
||||||
# 代码源与构建平台选型
|
# 代码源与构建平台选型
|
||||||
|
|
||||||
> 回答的问题:**「想简化是不是只能走 EdgeOne?」**
|
> 回答的问题:**「想简化是不是只能走 EdgeOne?」**
|
||||||
@@ -1,3 +1,6 @@
|
|||||||
|
> 📦 **本文档已归档**(2026-10-06)。它记录的是**当时的评估与方案**,其中的结论可能已被后续决策推翻。
|
||||||
|
> **请勿据此判断当前架构** —— 现行架构唯一事实源是 [`架构总览.md`](../../../架构总览.md)。
|
||||||
|
|
||||||
# 砍掉腾讯云 COS 中转层 —— 完整改造步骤
|
# 砍掉腾讯云 COS 中转层 —— 完整改造步骤
|
||||||
|
|
||||||
> 目标:把「build → COS → 中转机 → 又拍云 → 多吉云」这条绕路,
|
> 目标:把「build → COS → 中转机 → 又拍云 → 多吉云」这条绕路,
|
||||||
@@ -1,3 +1,6 @@
|
|||||||
|
> 📦 **本文档已归档**(2026-10-06)。它记录的是**当时的评估与方案**,其中的结论可能已被后续决策推翻。
|
||||||
|
> **请勿据此判断当前架构** —— 现行架构唯一事实源是 [`架构总览.md`](../../../架构总览.md)。
|
||||||
|
|
||||||
# 精简方案:只留 Cloudflare + Hugo
|
# 精简方案:只留 Cloudflare + Hugo
|
||||||
|
|
||||||
> 2026-10-04
|
> 2026-10-04
|
||||||
@@ -1,3 +1,6 @@
|
|||||||
|
> 📦 **本文档已归档**(2026-10-06)。它记录的是**当时的评估与方案**,其中的结论可能已被后续决策推翻。
|
||||||
|
> **请勿据此判断当前架构** —— 现行架构唯一事实源是 [`架构总览.md`](../../../架构总览.md)。
|
||||||
|
|
||||||
# 阿里云 ESA 评估(对比 EdgeOne)
|
# 阿里云 ESA 评估(对比 EdgeOne)
|
||||||
|
|
||||||
> 2026-10-04 · 问题:「阿里云也有个跟 EdgeOne 很像的服务,能不能考虑一下?」
|
> 2026-10-04 · 问题:「阿里云也有个跟 EdgeOne 很像的服务,能不能考虑一下?」
|
||||||
+142
@@ -0,0 +1,142 @@
|
|||||||
|
# 架构精简候选
|
||||||
|
|
||||||
|
> **用途**:本文是**待决策清单**,不是现状描述。现状看 [`../架构总览.md`](../架构总览.md)。
|
||||||
|
> 每条都是「已确认可以动、但需要你拍板」的项,附收益 / 代价 / 风险 / 怎么做。
|
||||||
|
>
|
||||||
|
> 更新时间:2026-10-06
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 一、复杂度的真实来源:不是「件数多」,是「跨了 6 个环境」
|
||||||
|
|
||||||
|
| 环境 | 谁在维护 | 上面跑什么 | 是否必需 |
|
||||||
|
|---|---|---|---|
|
||||||
|
| **腾讯云 CNB** | 托管 | 代码主仓 + 构建 + 发布(7 个 stage) | ★ 必需(发布的骨架) |
|
||||||
|
| **Cloudflare** | 托管 | 评论后端 + RSS + 证书只读面 + D1/KV + 200181.xyz 的 DNS | ★ 必需(零运维) |
|
||||||
|
| **国内机 `119.29.215.187`** | **自己** | 9 个容器(见下)+ 一堆手工 vhost | 部分必需 |
|
||||||
|
| **境外 VPS `23.254.236.47`** | **自己** | Gitea(代码辅仓) | ⚠️ **2026 年 11 月到期** |
|
||||||
|
| **家庭 F50 / OpenList** | **自己** | 离线加密备份 | ★ 必需(唯一的离线层) |
|
||||||
|
| **本机 Windows** | **自己** | 备份计划任务、本地写作前端 | 半必需 |
|
||||||
|
|
||||||
|
> **四台自维护设备 = 复杂度的真正来源**,而不是「用了几个云服务」。
|
||||||
|
> 托管服务再多也不累人(出问题找平台),自己维护的机器每一台都要有人记得它。
|
||||||
|
|
||||||
|
国内机 9 个容器里,**属于本项目的只有 3 个**:
|
||||||
|
|
||||||
|
| 容器 | 归属 | 状态 |
|
||||||
|
|---|---|---|
|
||||||
|
| `editor-api` | 本项目 | ✅ 写作后台的线上发布入口 |
|
||||||
|
| `cn-certkeeper` | 本项目 | ✅ 证书签发 + 部署 |
|
||||||
|
| `cn-dns-helper` | 本项目 | ⚠️ **疑似遗留**(见候选 2) |
|
||||||
|
| `1Panel-certimate-OKCO` | 历史遗留 | ⚠️ **可清**(见候选 1) |
|
||||||
|
| `1Panel-openresty` / `-mysql` | 用户的 | 面板与站点 |
|
||||||
|
| `1Panel-alist` / `vaultwarden` / `1Panel-frps` | 用户的 | 与本项目无关 |
|
||||||
|
|
||||||
|
→ **能动的只有两个**,而且都很干净。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 二、精简候选
|
||||||
|
|
||||||
|
### 候选 1 ★ certimate 容器 —— 停掉 `1Panel-certimate-OKCO`
|
||||||
|
|
||||||
|
| | |
|
||||||
|
|---|---|
|
||||||
|
| **现状** | 容器还在跑(`certimate/certimate:v0.4.32`)。但 **7 个工作流里「会签发并部署」的 2 条已停用**(`enabled=0`),只剩 3 条纯监控告警 |
|
||||||
|
| **为什么可以停** | 本项目已**完全接管**签发与部署。certimate 现在唯一的作用是「万一要回滚」,而它的凭据早就导出到 `secrets-backup/`,库文件也有 `.bak-*` |
|
||||||
|
| **收益** | 少一个常驻容器(内存是这台机器的短板:总 1967 MB / 已用 791 MB);少一个「静默竞争」风险源 |
|
||||||
|
| **风险** | 低。但**告警能力会消失** —— 三条监控工作流会随之失效。而本项目的证书监控已由 `cn-certkeeper` 的 `/status` + Worker 后台接管,**功能不重叠** |
|
||||||
|
| **怎么做** | `docker stop 1Panel-certimate-OKCO` → 观察 1~2 周(覆盖一次 04:10 自动续期 + 一次证书到期检查)→ 确认无碍再考虑删容器与数据卷。**别急着删**,先 stop |
|
||||||
|
|
||||||
|
> ⚠️ 若将来要停用,先确认「证书到期提醒」这一层有人接手(现在是 Worker 后台 + 探针)。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 候选 2 ★ `cn-dns-helper` 容器 —— 大概率已是遗留
|
||||||
|
|
||||||
|
| | |
|
||||||
|
|---|---|
|
||||||
|
| **它是什么** | 「DNS-01 助手」:接受 `POST /dns/txt`,代调用有 DNS 权限的 Cloudflare API 写 TXT 记录 |
|
||||||
|
| **当初为什么有** | Phase 1 时代**签发跑在 CF Worker 里**,而 Worker 那份 CF token 是 Workers/KV/D1 专用的(没有 Zone/DNS 权限)→ 只好让国内机代写 |
|
||||||
|
| **为什么现在不需要** | ★ 签发已搬到 `cn-certkeeper`(国内机),它**自带 dnsprovider**,直接调腾讯云 DNSPod / Cloudflare API。实测 `/preflight` **7/7 全过**,其中 `cloudflare → 200181.xyz` 报「**可读**」= 这份凭据有 Zone 权限 → **不需要中转** |
|
||||||
|
| **代码侧证据** | `deploy/cn-certkeeper/lib/dnsprovider.js` 里 `remote` 型是**兜底分支**(注释写明「用于 CF token 无 DNS 权限的场景」);Worker 侧 `dnsremoted.ts` **已无任何引用** |
|
||||||
|
| **收益** | 少一个常驻容器 + 少一个对外 HTTP 端点(虽然只绑回环) |
|
||||||
|
| **风险** | 低,但**要实测确认**:万一某条域名的 DNS-01 仍走 `remote`,停掉会让那次续期失败 |
|
||||||
|
| **怎么验证** | ① 查 `cn-certkeeper` 的凭据里有没有 `remote` 型(`/preflight` 的 dns 项只列了 `tencent-usj` / `tencent-tt` / `cloudflare`,**没有 remote**)② 停容器 → 手动跑一次单域续期(`renew-one.mjs`)→ 成功即可判死 |
|
||||||
|
| **结论** | **建议停掉**,跑一次续期验证 |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 候选 3 Gitea —— 迁到新机,还是干脆不留
|
||||||
|
|
||||||
|
**这是本轮最大的一刀**,完整分析见 [`Gitea迁移指南.md`](Gitea迁移指南.md) 第九节。摘要:
|
||||||
|
|
||||||
|
| 选项 | 收益 | 代价 |
|
||||||
|
|---|---|---|
|
||||||
|
| **A. 迁到新机** | 保留「在线可 clone、可按提交追溯、不受平台规则约束」的副本 | 继续养一台机器 + 一个要运维的实例(**且 Gitea 不参与构建、不参与发布**) |
|
||||||
|
| **B. 不迁,去掉辅仓** | 少一台机器、少一个部件,架构回到 **CNB 主仓 + F50 离线加密 bundle** 两层 | 少一层在线冗余(但离线层是**完整历史**,且已带失败告警) |
|
||||||
|
| C. 换托管平台私有仓 | 不用自己运维 | CNB 已是托管平台,再挂一家同性质的收益有限 |
|
||||||
|
|
||||||
|
**判断依据**:Gitea 现在挡的是「CNB 跟 GitHub 一样出问题」——
|
||||||
|
但**离线 bundle 已经覆盖了这个场景**。Gitea 多出来的独有价值只有
|
||||||
|
「**在线可浏览**」与「**可增量拉取**(不用等一天一次的备份)」。
|
||||||
|
这两点用不上,**B 就是合理的简化**。
|
||||||
|
|
||||||
|
> 若选 B:`deploy/gitea/` 留在仓库里即可(部署包与迁移清单留着,随时能重建),
|
||||||
|
> 然后按 `Gitea迁移指南.md` 第三节把那 9 处 `gitea` 引用清掉 ——
|
||||||
|
> **别忘了线上那两处**(`/srv/editor-api/.env`、`/srv/blog` 的 remote)。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 候选 4 写作前端两套并存(`write-server/` vs `write/`)
|
||||||
|
|
||||||
|
| | |
|
||||||
|
|---|---|
|
||||||
|
| **现状** | `write-server/`(Next.js,线上 `post.usj.cc`)+ `write/`(本地 Windows 前端),**架构总览已注明「功能重叠」** |
|
||||||
|
| **另外** | `editor-api/`(国内机)才是**真正的那条发布入口** —— 后台发的文章走它 |
|
||||||
|
| **收益** | 少维护一套前端;文档里的「写作系统」不再需要解释三个东西的关系 |
|
||||||
|
| **风险** | 取决于你实际用哪个。若两套都在用,就不是「精简」而是「迁移」 |
|
||||||
|
| **建议** | 先确认实际使用频率,再决定砍哪个。**本轮不动** |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 候选 5 三个手工 vhost 的证书(不是精简,是收尾)
|
||||||
|
|
||||||
|
`writeapi.usj.cc` 的证书**没被本项目纳管**(配置在 `/www/conf.d/`,不在 1Panel 站点树里),
|
||||||
|
实测仍是 **RSA / 到期 2026-12-07**,而本项目续期不会更新它 → **12 月会断**。
|
||||||
|
|
||||||
|
两条路:
|
||||||
|
- **A. 让 cn-certkeeper 覆盖它**:把 `/www/conf.d/writeapi.usj.cc.conf` 的证书路径指到
|
||||||
|
`openlist.usj.cc` 那种「已被纳管」的文件,或把它纳入部署目标
|
||||||
|
- **B. 在 1Panel 里把它建成正式站点**,自然被 `ssl/upload` + `sslID` 覆盖
|
||||||
|
|
||||||
|
详见 [`../架构总览.md`](../架构总览.md) §6 待办 #13。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 三、明确**不建议**动的(必要复杂度)
|
||||||
|
|
||||||
|
| 项 | 为什么保留 |
|
||||||
|
|---|---|
|
||||||
|
| **又拍云 + 多吉云 + EdgeOne 三个分发目标** | 境内/境外双线路是业务需求(境内走又拍云→多吉云,境外走 EdgeOne),不是历史堆积 |
|
||||||
|
| **Cloudflare Workers 全家(评论 + RSS + 证书只读面)** | 零服务器零运维,是本项目**最省事**的一层 |
|
||||||
|
| **国内机的 `editor-api`** | 写作后台的发布入口,没有替代品(CF Worker 跑不了 git push) |
|
||||||
|
| **国内机的 `cn-certkeeper`** | CF Worker 免费版 CPU 硬顶 10ms,签发跑不动;用户已否决 CF Paid(比这台机器还贵) |
|
||||||
|
| **家庭 F50 上的离线备份** | 唯一不依赖任何平台账号的层 |
|
||||||
|
| **三层留存** | 三层**失效模式不同**,不是重复(见 `架构总览.md` §5.3) |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 四、建议的执行顺序
|
||||||
|
|
||||||
|
```
|
||||||
|
1. 【立刻】候选 5 —— writeapi.usj.cc 证书纳管(12 月会断,有死线)
|
||||||
|
2. 【本周】候选 1 —— stop certimate 容器(零风险,观察即可)
|
||||||
|
3. 【本周】候选 2 —— 停 cn-dns-helper + 跑一次续期验证(大概率能省一个容器)
|
||||||
|
4. 【11 月前】候选 3 —— Gitea:迁 or 不留(★ 必须决定,机器要到期了)
|
||||||
|
5. 【有空】候选 4 —— 写作前端收敛(先看使用频率)
|
||||||
|
```
|
||||||
|
|
||||||
|
> 前三项做完,国内机上属于**本项目**的容器从 3 个降到 1 个(只剩 `editor-api`),
|
||||||
|
> 自维护环境从 6 个降到 5 个(去掉境外 VPS)。
|
||||||
|
> **这才是「感觉复杂」的真正解药 —— 减的是「要记得它」的东西,不是「存在于架构图里」的东西。**
|
||||||
@@ -1,9 +1,35 @@
|
|||||||
# 函数版证书管家(CF Worker)实施方案
|
# 证书管家
|
||||||
|
|
||||||
> **目标**:用 Cloudflare Worker 取代服务器上的 certimate,
|
> **文档定位**:本文既是**现状说明**(第一~二节 + §9.13),也是**决策沿革**(§8~§9,
|
||||||
|
> 含踩坑与实测数据)。要了解当前架构看前半部分;要改代码前先看 §8.4 / §9.9 / §9.11 / §9.12
|
||||||
|
> 这几节「易误判、勿回退」的坑。
|
||||||
|
>
|
||||||
|
> ⚠️ 标题曾叫「函数版证书管家(CF Worker)实施方案」—— 那是 Phase 1 的形态。
|
||||||
|
> **2026-10-06 晚定案后,签发与部署已搬到国内机容器**,Worker 只剩只读监控与后台。
|
||||||
|
> 沿革见 §9.1 与 §5.6;现行部署单元 `deploy/cn-certkeeper/`。
|
||||||
|
|
||||||
|
## 当前状态速览(2026-10-06 收工)
|
||||||
|
|
||||||
|
| 项 | 现状 |
|
||||||
|
|---|---|
|
||||||
|
| 签发 + 部署 | **国内机 Docker 容器 `cn-certkeeper`**(只绑 `127.0.0.1:8019`),每日 04:10 自动续期 |
|
||||||
|
| CF Worker(`blog-admin/`) | **只读**:监控 / 后台 / 探针。`/ssl/issue` 已改 **501 硬拒绝**,证书 cron 已移除 |
|
||||||
|
| 纳管域名 | `usj.cc` / `t-t.live` / `200181.xyz` 三组(事实源 `blog-admin/tools/certkeeper-config.mjs`) |
|
||||||
|
| 部署目标 | 多吉云 CDN + 1Panel(`119.29.215.187:3721`) |
|
||||||
|
| CA | LiteSSL / freessl.cn(EAB 继承 certimate 账户,见 §9.10) |
|
||||||
|
| 自测 | 125/125 通过;`npm run typecheck` 零错误 |
|
||||||
|
| 数据目录 | 容器内 `/data`,7 条凭据(AES-GCM)+ 1 条 config |
|
||||||
|
| **已知遗留** | `writeapi.usj.cc` 等 3 个手工 vhost 不在站点管理面内(§9.14 末节)—— 证书是文件拷贝,需单独纳管 |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 原始方案(Phase 1 形态,保留供对照)
|
||||||
|
|
||||||
|
> **当初目标**:用 Cloudflare Worker 取代服务器上的 certimate,
|
||||||
> 申请 + 续期 + 部署证书(多吉云 CDN + 1Panel),把 certimate 这个服务精简掉。
|
> 申请 + 续期 + 部署证书(多吉云 CDN + 1Panel),把 certimate 这个服务精简掉。
|
||||||
|
> —— ⚠️ 该目标**已被 §9 推翻**:Worker 免费版 CPU 硬顶 10ms/请求,签发跑不动,改由国内机承担。
|
||||||
|
|
||||||
**已确认的决策(2026-10-06)**
|
**当时确认的决策(2026-10-06)**
|
||||||
|
|
||||||
| 项 | 决定 |
|
| 项 | 决定 |
|
||||||
|---|---|
|
|---|---|
|
||||||
@@ -7,7 +7,7 @@
|
|||||||
* (表面成功、实际随机损坏,可能几个月后才发现)。bundle 是单文件顺序写,安全。
|
* (表面成功、实际随机损坏,可能几个月后才发现)。bundle 是单文件顺序写,安全。
|
||||||
*
|
*
|
||||||
* 为什么默认加密:
|
* 为什么默认加密:
|
||||||
* 本仓库历史里含 .env、TLS 私钥、GITEA_SECRETS.md。目标介质是手机内部存储,
|
* 本仓库历史里含 .env、TLS 私钥、docs/GITEA_SECRETS.md。目标介质是手机内部存储,
|
||||||
* 未加密等于把密钥明文放在一台可能被刷机/丢失/他人访问的设备上。
|
* 未加密等于把密钥明文放在一台可能被刷机/丢失/他人访问的设备上。
|
||||||
*
|
*
|
||||||
* 为什么不用 gpg:
|
* 为什么不用 gpg:
|
||||||
|
|||||||
@@ -1,28 +1,31 @@
|
|||||||
# 优世界博客 · 架构总览
|
# 优世界博客 · 架构总览
|
||||||
|
|
||||||
> 更新时间:2026-10-04(CNB 迁移完成当日)
|
> 更新时间:2026-10-06
|
||||||
> 状态:**迁移已落地并跑通**(四线路全绿,单次发布约 3.5 分钟)
|
> 状态:**迁移已落地并跑通**(四线路全绿,单次发布约 3.5 分钟)
|
||||||
> 本文档只描述**现状**;迁移前的复杂度审计与选型过程见文末「相关文档」。
|
> 本文档只描述**现状**;决策期的一次性评估与已完结方案见 [`docs/archive/`](docs/archive/)。
|
||||||
|
> 文档地图见 [`docs/README.md`](docs/README.md)。
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 0. 一句话
|
## 0. 一句话
|
||||||
|
|
||||||
四个子系统,一条 **3 步**的托管发布链路。构建与发布已从「自建 Gitea + act_runner + 广州中转机」迁到
|
**五个子系统**,一条 **3 步**的托管发布链路。构建与发布已从「自建 Gitea + act_runner + 广州中转机」迁到
|
||||||
**腾讯云 CNB(cnb.cool)** —— **需要自己运维的机器从 3 台降到 0 台**。
|
**腾讯云 CNB(cnb.cool)** —— 发布链路上**需要自己运维的机器从 3 台降到 0 台**
|
||||||
|
(另有一台国内机跑写作后台与证书签发,但都不在构建链路里)。
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 1. 全景
|
## 1. 全景
|
||||||
|
|
||||||
### 1.1 四个子系统
|
### 1.1 五个子系统
|
||||||
|
|
||||||
| # | 子系统 | 技术栈 | 跑在哪 | 状态 |
|
| # | 子系统 | 技术栈 | 跑在哪 | 状态 |
|
||||||
|---|---|---|---|---|
|
|---|---|---|---|---|
|
||||||
| **1** | **内容系统** | Hugo 0.128.2 extended + Ying 主题,138 篇 md;产物约 3200 文件 / 424MB | 产物分发到 3 个 CDN | 正常 |
|
| **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` | ✅ 零服务器零运维 |
|
| **2** | **评论系统** | `blog-admin/` = artalk-cf(Artalk v2 兼容服务端)+ RSS 机器人 | Cloudflare Workers + D1 + KV → `api.200181.xyz` | ✅ 零服务器零运维 |
|
||||||
| **3** | **写作系统** | `write-server/`(Next.js 16,`post.usj.cc`)<br>`write/`(本地 Windows 前端) | 独立 Docker 主机/本机 | 可用(两套前端功能重叠) |
|
| **3** | **写作系统** | `write-server/`(Next.js 16,`post.usj.cc`)<br>`write/`(本地 Windows 前端)<br>`editor-api/`(国内机轻量后端,实为线上那条发布入口) | 独立 Docker 主机/本机/国内机 | 可用(两套前端功能重叠) |
|
||||||
| **4** | **发布基础设施** | **CNB 流水线**(`.cnb.yml`)+ 又拍云 + 多吉云 + EdgeOne | 腾讯云 CNB(**托管**) | **新建,已跑通** |
|
| **4** | **发布基础设施** | **CNB 流水线**(`.cnb.yml`)+ 又拍云 + 多吉云 + EdgeOne | 腾讯云 CNB(**托管**) | **已跑通** |
|
||||||
|
| **5** | **证书系统** | 证书管家(自研):ACME 签发 + DNS-01 + 多目标部署(多吉云 / 1Panel) | **国内机 Docker `cn-certkeeper`**(签发+部署)<br>+ CF Worker(**只读**:监控/后台/探针) | ✅ 已上线,每日 04:10 自动续期(详见 §5.7) |
|
||||||
|
|
||||||
### 1.2 服务与地址地图
|
### 1.2 服务与地址地图
|
||||||
|
|
||||||
@@ -38,6 +41,8 @@
|
|||||||
| **国内加速** | 多吉云 CDN | 回源又拍云 |
|
| **国内加速** | 多吉云 CDN | 回源又拍云 |
|
||||||
| **境外线路** | EdgeOne Pages(项目 `hugo-blog`,`--area overseas`) | 腾讯 EdgeOne 国际站 |
|
| **境外线路** | EdgeOne Pages(项目 `hugo-blog`,`--area overseas`) | 腾讯 EdgeOne 国际站 |
|
||||||
| **评论后端** | `api.200181.xyz` | Cloudflare Workers |
|
| **评论后端** | `api.200181.xyz` | Cloudflare Workers |
|
||||||
|
| **证书签发** | 国内机 `119.29.215.187` → `127.0.0.1:8019`(容器 `cn-certkeeper`) | ACME 签发 + DNS-01 + 多吉云/1Panel 部署;`deploy/cn-certkeeper/`,每日 04:10 续期 |
|
||||||
|
| **证书只读面** | `api.200181.xyz/api/v2/ssl*` | CF Worker 上的监控 / 后台 / 探针,**只读**(`/ssl/issue` 已改 501 硬拒绝,见 §5.7) |
|
||||||
| **通知** | QQ 邮件(`imql@qq.com`) | 已收敛为**单一通道**;同时承担备份失败告警(§5.6) |
|
| **通知** | QQ 邮件(`imql@qq.com`) | 已收敛为**单一通道**;同时承担备份失败告警(§5.6) |
|
||||||
|
|
||||||
> 关键点:境内、境外仍是**两条独立线路**,但**由同一条流水线一次推完** ——
|
> 关键点:境内、境外仍是**两条独立线路**,但**由同一条流水线一次推完** ——
|
||||||
@@ -77,7 +82,7 @@
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 3. 流水线细节(`.cnb.yml`,284 行)
|
## 3. 流水线细节(`.cnb.yml`,337 行)
|
||||||
|
|
||||||
| 触发 | 条件 | 说明 |
|
| 触发 | 条件 | 说明 |
|
||||||
|---|---|---|
|
|---|---|---|
|
||||||
@@ -315,7 +320,7 @@ GitHub 那次 AUP 清空就是活证。自建 Gitea 是唯一「不受第三方
|
|||||||
把 bare repo 挂上去直接 `git push` 会让对象写坏 —— 表面成功、实际随机损坏,
|
把 bare repo 挂上去直接 `git push` 会让对象写坏 —— 表面成功、实际随机损坏,
|
||||||
可能几个月后才发现。bundle 是**单文件顺序写**,没有这个问题。
|
可能几个月后才发现。bundle 是**单文件顺序写**,没有这个问题。
|
||||||
|
|
||||||
**为什么加密**:本仓库历史里含 `.env`、TLS 私钥、`GITEA_SECRETS.md`。
|
**为什么加密**:本仓库历史里含 `.env`、TLS 私钥、`docs/GITEA_SECRETS.md`。
|
||||||
介质是一台随身设备的内部存储,明文等于把密钥放在可能丢失 / 刷机 / 送修的设备上。
|
介质是一台随身设备的内部存储,明文等于把密钥放在可能丢失 / 刷机 / 送修的设备上。
|
||||||
OpenList 的登录只保护**访问通道**,不保护**存储介质** —— F50 丢了拆开就能读。
|
OpenList 的登录只保护**访问通道**,不保护**存储介质** —— F50 丢了拆开就能读。
|
||||||
|
|
||||||
@@ -431,6 +436,51 @@ git clone blog.bundle blog # 或 git fetch blog.bundle 'refs/*:refs/*'
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
### 5.7 证书管家(子系统 5)
|
||||||
|
|
||||||
|
**职责划分 —— 一句话:签发与部署在国内机,Worker 只有只读。**
|
||||||
|
|
||||||
|
| 层 | 职责 | 跑在哪 |
|
||||||
|
|---|---|---|
|
||||||
|
| 签发 + 部署 | ACME(LiteSSL,EAB 继承 certimate 账户)· DNS-01 · 写多吉云 CDN · 写 1Panel | **国内机 Docker `cn-certkeeper`**,只绑 `127.0.0.1:8019`,每日 **04:10** 自动续期 |
|
||||||
|
| 只读 | 监控 / 后台页面 / 探针 | CF Worker(`blog-admin/`),路由 `/api/v2/ssl*` |
|
||||||
|
|
||||||
|
**为什么非要这么分**:CF Worker **免费版 CPU 硬顶 10ms/请求**(cron 同样 10ms),
|
||||||
|
签发要跑十来次 JWS 签名,**根本跑不动**;而 `[limits] cpu_ms` 在免费版会让**整个部署失败**(code 100328)。
|
||||||
|
用户否决了 CF Paid($5/月 ≈ ¥36/月 —— 比这台本来就在跑的国内机还贵)。
|
||||||
|
|
||||||
|
**三条不能破的红线**:
|
||||||
|
|
||||||
|
1. **Worker 不得签发** —— `POST /ssl/issue` 已改成 **501 硬拒绝**,证书 cron 已从 `wrangler.toml` 移除
|
||||||
|
2. **证书路由只认 Bearer 会话**,绝不用 `isAdminRequest` —— 后者有 Artalk 老客户端兜底
|
||||||
|
(`?name=<管理员名>&email=<管理员邮箱>` 即视为管理员),而这俩是**公开信息**。
|
||||||
|
一旦混用,任何人拼 query 就能读走 TLS 私钥。
|
||||||
|
3. **角色判定必须正着枚举放行**(`role === 'admin' || role === 'ssl'`),
|
||||||
|
禁止写成 `role !== 'editor'` —— 以后新增角色会**静默获得私钥权限**。
|
||||||
|
(角色体系见 `blog-admin/`;`ssl` 与 `editor` **平级、互不包含**)
|
||||||
|
|
||||||
|
**纳管域名**(唯一事实源 `blog-admin/tools/certkeeper-config.mjs`):
|
||||||
|
|
||||||
|
| 域名 | 部署目标 | 备注 |
|
||||||
|
|---|---|---|
|
||||||
|
| `usj.cc` | 多吉云 CDN + 1Panel | SAN 为 `usj.cc;*.usj.cc` |
|
||||||
|
| `t-t.live` | 1Panel(5 个站点) | 本项目**已接管**,certimate 的竞争工作流已停用 |
|
||||||
|
| `200181.xyz` | 1Panel | |
|
||||||
|
|
||||||
|
**与 certimate 的关系**:certimate 容器仍在机器上,但**凡「会签发并部署」的工作流都已停用**
|
||||||
|
(`enabled=0`)—— 否则它会用 RSA 证书覆盖本项目签的 ECC 证书,且**60 天后才爆、爆得静默**。
|
||||||
|
保留的只有三条**纯监控告警**工作流。
|
||||||
|
|
||||||
|
**已知遗留**:
|
||||||
|
|
||||||
|
- `writeapi.usj.cc` / `dnsapi.usj.cc` / `vaultwarden` 三个**手工 nginx vhost 不归 1Panel 站点管理** ——
|
||||||
|
证书是**文件拷贝**,与证书库记录解耦,`/websites/{id}/https` 碰不到它们 → 需单独纳管
|
||||||
|
- 动代码前必看 [`docs/证书管家.md`](docs/证书管家.md) 的 **§8.4 / §9.9 / §9.11 / §9.12** 四节
|
||||||
|
「易误判、勿回退」的坑(ACME 客户端 bug、CSR 三层 SEQ、`ssl/update` 不物化站点文件、
|
||||||
|
1Panel HTTPS 字段名是大写 `SSL` 等)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## 6. 遗留待办
|
## 6. 遗留待办
|
||||||
|
|
||||||
| # | 项 | 说明 |
|
| # | 项 | 说明 |
|
||||||
@@ -441,21 +491,30 @@ git clone blog.bundle blog # 或 git fetch blog.bundle 'refs/*:refs/*'
|
|||||||
| 4 | `gitea` remote | ✅ **已恢复**(2026-10-06):作为代码同步辅仓重新挂上,`pushall` 恢复双推(`origin` + `gitea`)。接入时 Gitea 停在 `ed38f938`,一次 fast-forward 追平(+57 提交),**未强推、未丢历史**。发布链路 5 处默认值同步改回 `origin,gitea`(`bootstrap.sh` / `docker-compose.editor.yml` / `server.mjs` / `README.md` / `setup-cnb-remotes.sh`)。**线上 editor-api 容器也已切双推**(见 #12) |
|
| 4 | `gitea` remote | ✅ **已恢复**(2026-10-06):作为代码同步辅仓重新挂上,`pushall` 恢复双推(`origin` + `gitea`)。接入时 Gitea 停在 `ed38f938`,一次 fast-forward 追平(+57 提交),**未强推、未丢历史**。发布链路 5 处默认值同步改回 `origin,gitea`(`bootstrap.sh` / `docker-compose.editor.yml` / `server.mjs` / `README.md` / `setup-cnb-remotes.sh`)。**线上 editor-api 容器也已切双推**(见 #12) |
|
||||||
| 5 | GitHub 侧旧 workflow | ✅ **已删除**(2026-10-06)。整个 `.github/` 目录移除(`deploy.yml` 1169 行 + `aliyun-backup.yml` + `cleanup.yml`),共 −1284 行 —— **GitHub 已不再是任何环节的依赖**。旧实现可在 git 历史中查 |
|
| 5 | GitHub 侧旧 workflow | ✅ **已删除**(2026-10-06)。整个 `.github/` 目录移除(`deploy.yml` 1169 行 + `aliyun-backup.yml` + `cleanup.yml`),共 −1284 行 —— **GitHub 已不再是任何环节的依赖**。旧实现可在 git 历史中查 |
|
||||||
| 6 | 令牌 scope | 缺 `repo-cnb-history:r`(读构建日志);补上后 agent 可自行排错 |
|
| 6 | 令牌 scope | 缺 `repo-cnb-history:r`(读构建日志);补上后 agent 可自行排错 |
|
||||||
| 7 | Gitea 主机 / 广州中转机 | **Gitea 主机已回归**(2026-10-06):作为代码辅仓,本机直连 `23.254.236.47:3001` 即可推。广州中转机仍不参与 git 链路 |
|
| 7 | ★ **Gitea 主机到期** | **2026 年 11 月**,境外 VPS `23.254.236.47` 到期 —— 迁移是**有死线的待办**,不是可选项。现在迁移面已大幅缩小(**只需搬 Gitea 本体,runner / upyun-sync / 中转机都不需要**,因为构建已在 CNB),完整步骤与「本仓 9 处写死旧地址」的清单见 [`docs/Gitea迁移指南.md`](docs/Gitea迁移指南.md)。⚠️ 那篇第九节还给出了「干脆不留这个辅仓」的选项与判断依据 |
|
||||||
| 8 | `README.md` | ✅ 已更新(去 GitHub 化 + 补上备份脚本说明) |
|
| 8 | `README.md` | ✅ 已更新(去 GitHub 化 + 补上备份脚本说明) |
|
||||||
| 9 | **敏感文件仍在跟踪中** | `.env`、`GITEA_SECRETS.md`、`write-server/nginx/ssl/privkey.pem`、`content/posts/2024/.../setup-secrets.png` —— 若还要推任何新平台,先 `git rm --cached` 并轮换凭据。⚠️ 当初「不改写历史」的唯一顾虑是备份会分叉;**GitHub 那份已消失,这个顾虑没有了** → `git filter-repo` 现在是可行窗口(代价:全部提交 SHA 改变)。离线 bundle 已加密(§5.6),不受此影响 |
|
| 9 | **敏感文件仍在跟踪中** | `.env`、`docs/GITEA_SECRETS.md`、`write-server/nginx/ssl/privkey.pem`、`content/posts/2024/.../setup-secrets.png` —— 若还要推任何新平台,先 `git rm --cached` 并轮换凭据。⚠️ 当初「不改写历史」的唯一顾虑是备份会分叉;**GitHub 那份已消失,这个顾虑没有了** → `git filter-repo` 现在是可行窗口(代价:全部提交 SHA 改变)。离线 bundle 已加密(§5.6),不受此影响 |
|
||||||
| 10 | **整仓离线备份** | ✅ **已上线**(2026-10-06),现为**备选**异地备份(在线那一路是自建 Gitea 辅仓),见 §5.6。计划任务 `Blog-BundleBackup` 每天 03:30 跑,端到端已验证;失败会发告警邮件(已实测)。**2026-10-06 补**:打包前加 `git fetch --all` —— 原来备的是「本机已知 ref」的快照,后台新发的文章可能一份都不在里面,且备份照样报成功(§5.6)。待补三件安全项:把 `BACKUP_PASSPHRASE` 抄进密码管理器;给 OpenList **改掉 admin 密码 + 开两步验证**(现 `otp: false`,且旧密码已出现在对话里);确认 5244 端口**未暴露到公网** |
|
| 10 | **整仓离线备份** | ✅ **已上线**(2026-10-06),现为**备选**异地备份(在线那一路是自建 Gitea 辅仓),见 §5.6。计划任务 `Blog-BundleBackup` 每天 03:30 跑,端到端已验证;失败会发告警邮件(已实测)。**2026-10-06 补**:打包前加 `git fetch --all` —— 原来备的是「本机已知 ref」的快照,后台新发的文章可能一份都不在里面,且备份照样报成功(§5.6)。待补三件安全项:把 `BACKUP_PASSPHRASE` 抄进密码管理器;给 OpenList **改掉 admin 密码 + 开两步验证**(现 `otp: false`,且旧密码已出现在对话里);确认 5244 端口**未暴露到公网** |
|
||||||
| 11 | **F50 存储目录的使用约定** | `/本地/` 下的 `刷机` / `系统` / `资料` / `软件` / `驱动` / `备份` 都是用户自己在管的类别。**本项目的 bundle 只写 `备份/blog-bundle/` 子目录**,不与用户手工备份(`github-zqlit-*`、`local-repos-*`)混放 |
|
| 11 | **F50 存储目录的使用约定** | `/本地/` 下的 `刷机` / `系统` / `资料` / `软件` / `驱动` / `备份` 都是用户自己在管的类别。**本项目的 bundle 只写 `备份/blog-bundle/` 子目录**,不与用户手工备份(`github-zqlit-*`、`local-repos-*`)混放 |
|
||||||
| 12 | **editor-api 容器的三层留存** | ✅ **已落地**(2026-10-06,国内机 `119.29.215.187`):`PUSH_REMOTES=origin,gitea`(CNB 主仓 + 自建 Gitea 备份仓),文件层走 §5.6 的加密 bundle。实测:容器内推 `origin` ✅ / 推 `gitea` ✅(临时分支推完即删),`/health` 返回 `remotes:["origin","gitea"]`,三处 `main` 对齐 `448b898e`。接入时 `/srv/blog` 落后 10 个提交,一次 fast-forward 追平 |
|
| 12 | **editor-api 容器的三层留存** | ✅ **已落地**(2026-10-06,国内机 `119.29.215.187`):`PUSH_REMOTES=origin,gitea`(CNB 主仓 + 自建 Gitea 备份仓),文件层走 §5.6 的加密 bundle。实测:容器内推 `origin` ✅ / 推 `gitea` ✅(临时分支推完即删),`/health` 返回 `remotes:["origin","gitea"]`,三处 `main` 对齐 `448b898e`。接入时 `/srv/blog` 落后 10 个提交,一次 fast-forward 追平 |
|
||||||
|
| 13 | ★ **证书管家的两个遗留** | 见 §5.7。**① `writeapi.usj.cc` 的证书没纳管**(真问题,会到期):它的 nginx 配置在 `/www/conf.d/writeapi.usj.cc.conf` —— **不在 `/www/sites/` 管理树里**,所以 1Panel 的 `ssl/upload`+`sslID` 物化时碰不到它。现状实测:`CN=usj.cc` / **RSA** / 到期 **2026-12-07**,而本项目续期**不会更新它** → 12 月会断。**② `dnsapi.usj.cc` 没上 HTTPS**(`ssl/` 目录空、源站握手失败)。<br>(附带澄清:`200181.xyz` 公网走 Cloudflare,看到的 LE 证书是 **CF 自家的边缘证书**,与本项目无关;源站 `ssh.200181.xyz` 已是本项目签的 `*.200181.xyz` / 2027-01-04 ✅) |
|
||||||
|
| 14 | **架构复杂度盘点** | 「感觉架构还是复杂了」的正面回应 → 已盘点:**跨 6 个环境,其中 4 个要自己维护**,这才是复杂度的来源;国内机 9 个容器里属于本项目的只有 3 个,能动的只有 2 个。**5 个精简候选 + 建议执行顺序**见 [`docs/架构精简候选.md`](docs/架构精简候选.md):certimate 容器可停、`cn-dns-helper` 大概率是遗留、Gitea 迁 or 不留、两套写作前端收敛、writeapi 证书纳管 |
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 附:相关文档
|
## 附:相关文档
|
||||||
|
|
||||||
- `CNB构建落地方案.md` — 迁移实施方案与实测数据
|
文档只有两个入口在根目录(`README.md`、本文);其余在 `docs/`,一次性的评估与已完结方案在 `docs/archive/`。
|
||||||
- `代码源与构建平台选型.md` — 平台对比(CNB / Gitee / GitLab / EdgeOne / 阿里云 ESA)
|
完整地图见 [`docs/README.md`](docs/README.md)。
|
||||||
- `砍COS改造步骤.md` — COS 下线记录
|
|
||||||
- `EdgeOne双区域方案评估.md`、`Gitee方案评估.md`、`阿里云ESA评估.md`、`精简方案-只留CF和Hugo.md` — 决策期评估
|
| 文档 | 内容 |
|
||||||
|
|---|---|
|
||||||
|
| `docs/证书管家.md` | ★ 证书管家(签发在国内机,Worker 只读):现状 + 决策沿革 + 勿回退的坑 |
|
||||||
|
| `docs/Gitea迁移指南.md` | ★ 自建 Gitea 搬迁时**必须同步改的全部位置** + 验证清单 |
|
||||||
|
| `docs/架构精简候选.md` | 复杂度盘点 + 5 个可精简候选(待决策,含收益/代价/风险) |
|
||||||
|
| `docs/CNB构建落地方案.md` | 迁 CNB 的实施方案与实测数据 |
|
||||||
|
| `docs/GITEA_SECRETS.md` | Gitea / 相关凭据清单(**含明文,勿外传**) |
|
||||||
|
| `docs/archive/` | 决策期评估与已完结方案(Gitee / EdgeOne / ESA / 精简方案 / COS 下线 / 评论修复 / 诊断报告 …) |
|
||||||
|
|
||||||
**证据出处(现行)**:`.cnb.yml`(284 行)、`deploy/Dockerfile`、`bin/linux/hugo`、
|
**证据出处(现行)**:`.cnb.yml`(284 行)、`deploy/Dockerfile`、`bin/linux/hugo`、
|
||||||
`scripts/send_mail.js`、`scripts/refresh_cdn.js`、`scripts/setup-cnb-remotes.sh`、
|
`scripts/send_mail.js`、`scripts/refresh_cdn.js`、`scripts/setup-cnb-remotes.sh`、
|
||||||
|
|||||||
Reference in new issue
Block a user