diff --git a/README.md b/README.md index 92c8ee98..dfeb5c55 100644 --- a/README.md +++ b/README.md @@ -1,20 +1,25 @@ # 优世界博客(usj.cc) -Hugo 静态博客 + 自研评论后端 + 写作后台。 +Hugo 静态博客 + 自研评论后端 + 写作后台 + 证书管家。 **构建与发布跑在腾讯云 CNB**(国内节点),单次发布约 3.5 分钟,境内/境外两条线路一次推完。 -> 架构全貌、迁移前后对比、运维要点 → [`架构总览.md`](架构总览.md) +> 📖 **想先看懂全局** → [`架构总览.md`](架构总览.md)(架构唯一事实源) +> 🗂 **想找某份文档** → [`docs/README.md`](docs/README.md)(文档地图) +> 🔧 **要动手改东西** → 先看下面「项目构成」找准子系统,再看对应的专题文档 --- -## 一、项目构成 +## 一、项目构成(五个子系统) -| 子系统 | 位置 | 技术栈 | -|---|---|---| -| **内容** | `content/`、`themes/Ying/` | Hugo 0.128.2 extended + Ying 主题 | -| **评论后端** | `blog-admin/` | artalk-cf:Cloudflare Workers + D1 + KV(`api.200181.xyz`) | -| **写作后台** | `write-server/`(线上 `post.usj.cc`)、`write/`(本地 Windows) | Next.js | -| **发布** | `.cnb.yml`、`deploy/` | CNB 流水线 + Dockerfile | +| # | 子系统 | 位置 | 技术栈 | 部署形态 | +|---|---|---|---|---| +| 1 | **内容** | `content/`、`themes/Ying/` | Hugo 0.128.2 extended + Ying 主题 | 产物分发到 3 个 CDN | +| 2 | **评论后端** | `blog-admin/` | artalk-cf:Cloudflare Workers + D1 + KV | 托管(`api.200181.xyz`) | +| 3 | **写作后台** | `write-server/`(线上 `post.usj.cc`)、`write/`(本地)、`editor-api/`(线上发布入口) | Next.js / 轻量 Node(零依赖) | 独立主机 / 本机 / 国内机容器 | +| 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/ -├── .cnb.yml # ★ CNB 流水线(push + 每日定时) -├── deploy/Dockerfile # 构建镜像(hugo 二进制由 bin/linux/hugo 提供) -├── bin/linux/hugo # Hugo extended 0.128.2(linux/amd64,供 CNB 构建用) -├── content/ -│ ├── posts/<年>/<日期>-<标题>/ # 文章(Page Bundle,index.md + 图片) -│ ├── about.md / links.md / circles.md / archives.md -├── themes/Ying/ # 主题(layout / assets / data) -├── static/ # 原样复制进产物(emotion 表情、image、js …) -├── blog-admin/ # 评论后端(artalk-cf) -├── write-server/ # 线上写作后台 -├── write/ # 本地写作前端 -├── scripts/ # 各类工具脚本(见第六节) +├── README.md # ★ 本文(项目入口) +├── 架构总览.md # ★ 架构唯一事实源 +├── docs/ # 专题文档(地图见 docs/README.md) +│ ├── 证书管家.md +│ ├── Gitea迁移指南.md # ★ Gitea 换机器时照做 +│ ├── CNB构建落地方案.md +│ ├── GITEA_SECRETS.md # ⚠️ 含明文凭据 +│ └── archive/ # 已归档:决策期评估 + 已完结方案 +├── .cnb.yml # CNB 流水线(push 触发 + 每日定时) +├── content/ # 文章(Page Bundle:index.md + 图片) +├── themes/Ying/ # 主题 +├── static/ # 原样复制进产物(表情、图片、js …) ├── 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/) - │ git pushall (= git push origin main ; git push gitea main) - ▼ -origin → CNB 主仓 zqlit/blog ──触发──► CNB 流水线(国内节点,约 3.5 分钟) - ├─ Hugo 构建 - ├─ 同步到又拍云(境内源站) - ├─ 刷新又拍云 CDN - ├─ 刷新多吉云 CDN - ├─ 部署 EdgeOne Pages(境外线路) - └─ 邮件通知 - -gitea → 自建 Gitea(23.254.236.47:3001) 代码同步辅仓:只推不拉、不参与构建 +① 写作 write-server(网页)或 write/(本地 Windows) + │ +② 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 辅仓,只推不拉) + ▼ +③ CNB 流水线(国内节点,约 3.5 分钟) + ├─ Hugo 构建 → 同步又拍云 → 刷新又拍云 CDN → 刷新多吉云 CDN + └─ 部署 EdgeOne Pages(境外线路)→ 上报状态 → 邮件通知 ``` -- **推送**:`git pushall` —— 依次推 `origin`(CNB 主仓,触发构建)与 `gitea`(自建 Gitea 代码同步辅仓) - ;只推主仓用 `git push origin main` +- **触发**:推送到 `main`;另有每日 `0 9 * * *`(北京时间)定时构建 +- **密钥**:全部来自 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`, **主仓成功即算发布成功**,辅仓失败只警告不阻断 - ★ **两边同一条铁律:任何提交都必须先落到 CNB** —— pull 源只有 `origin`, 只推 `gitea` 的提交后台看不见,下次发布会因 non-fast-forward 被拒 -- **备选异地备份**:**不走 git 远端**。本机计划任务每天 03:30 把整仓 bundle - (**打包前先 `git fetch --all`**,否则备的是过期快照)加密后传到中兴 F50 上的 - OpenList(见 `架构总览.md` §5.6) -- **触发**:推送到 `main`;另有每日 `0 9 * * *`(北京时间)定时构建 -- **密钥**:全部来自 CNB 密钥仓库 `zqlit/blog-secrets`,经 `.cnb.yml` 的 `imports` 注入, - **仓库里没有任何明文密钥** -- 改动 `main` 即自动上线,本地无需构建 +- **离线备份**:本机计划任务每天 03:30 把整仓 bundle(**打包前先 `git fetch --all`**, + 否则备的是过期快照)加密后传到 F50 上的 OpenList(见 `架构总览.md` §5.6) --- -## 五、三个子系统 - -### 内容系统 - -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/`) +## 五、常用脚本(`scripts/`) | 脚本 | 用途 | 在哪跑 | |---|---|---| | `add_draft_to_hidden.py` | 构建前把 `status: hidden` 转成草稿 | **CI** | | `refresh_cdn.js` | 刷新多吉云 CDN(零依赖) | **CI** | | `send_mail.js` | 构建结果邮件通知(零依赖 SMTP) | **CI** | -| `setup-cnb-remotes.sh` | 切换/重建 git 远端(CNB 主仓 + 自建 Gitea 辅仓;顺手清掉退役远端) | 本机 | -| `backup-run.mjs` | 备份的推荐入口:跑 `backup-bundle` + **失败时发告警邮件** | 本机/计划任务 | -| `backup-bundle.mjs` | `git fetch --all` → 整仓 bundle → AES-256-GCM 加密 → WebDAV 传中兴 F50(见 架构总览 §5.6) | 本机/计划任务 | +| `fetch_snapshots.sh` | 构建期拉 conf/友链/友圈快照 → `data/` | **CI** | +| `setup-cnb-remotes.sh` | 重建 git 远端(CNB 主仓 + Gitea 辅仓;顺手清退役远端) | 本机 | +| `backup-run.mjs` | 备份推荐入口:跑 `backup-bundle` + **失败时发告警邮件** | 本机/计划任务 | +| `backup-bundle.mjs` | `git fetch --all` → 整仓 bundle → AES-256-GCM 加密 → WebDAV 传 F50 | 本机/计划任务 | | `backup-task.cmd` | 上面的计划任务入口(每天 03:30;**内容必须全 ASCII**) | 计划任务 | | `optimize_images.js` | 图片批量压缩优化 | 本机 | | `generate_circle_data.js` | 抓友链 RSS 生成朋友圈数据 | 本机 | @@ -150,18 +154,22 @@ Hugo + Ying 主题。`hugo.toml` 控站点信息、永久链接、Artalk 地址 | `add_ancient_chars.py` / `check_ancient_chars.py` / `merge_chars.py` | 字体生僻字增补与校验 | 本机 | | `cleanup_duplicates.js` / `migrate_slugs.js` | 一次性维护脚本 | 本机 | -> `deploy_*.sh`(又拍云 / EdgeOne / 定时)是本机手动部署的旧入口,**日常已不需要**—— +> `deploy_*.sh`(又拍云 / EdgeOne / 定时)是本机手动部署的旧入口,**日常已不需要** —— > 推送 `main` 由 CNB 自动完成。 --- -## 七、相关文档 +## 六、文档地图 + +只列导航,完整说明见 [`docs/README.md`](docs/README.md)。 | 文档 | 内容 | |---|---| -| `架构总览.md` | **当前架构全貌**(子系统、发布链路、迁移前后对比、运维要点) | -| `CNB构建落地方案.md` | 迁 CNB 的实施方案与实测数据 | -| `代码源与构建平台选型.md` | 平台对比(CNB / Gitee / GitLab / EdgeOne / 阿里云 ESA) | -| `砍COS改造步骤.md` | 腾讯云 COS 下线记录 | -| `blog-admin/README.md` | 评论后端完整说明 | -| `blog-admin/部署清单.md` | 评论后端部署步骤 | +| [`架构总览.md`](架构总览.md) | ★ **当前架构全貌**(五个子系统、发布链路、运维要点、遗留待办) | +| [`docs/证书管家.md`](docs/证书管家.md) | ★ 证书子系统:现状 + 决策沿革 + 勿回退的坑 | +| [`docs/Gitea迁移指南.md`](docs/Gitea迁移指南.md) | ★ Gitea 换机器:**本仓 9 处写死旧地址**的清单 + 验证步骤 | +| [`docs/架构精简候选.md`](docs/架构精简候选.md) | 复杂度盘点与 5 个可精简候选(想「让架构简单点」时看) | +| [`docs/CNB构建落地方案.md`](docs/CNB构建落地方案.md) | 迁 CNB 的实施方案与实测数据 | +| [`docs/archive/`](docs/archive/) | 决策期评估与已完结方案(**不代表现状**) | +| `blog-admin/README.md`、`blog-admin/部署清单.md` | 评论后端完整说明 | +| `editor-api/README.md` | 写作后台 API(含「落盘:写一次,存三处」) | diff --git a/gitea-backup/.env.example b/deploy/gitea/.env.example similarity index 100% rename from gitea-backup/.env.example rename to deploy/gitea/.env.example diff --git a/gitea-backup/.gitignore b/deploy/gitea/.gitignore similarity index 50% rename from gitea-backup/.gitignore rename to deploy/gitea/.gitignore index 69645770..ac43bf71 100644 --- a/gitea-backup/.gitignore +++ b/deploy/gitea/.gitignore @@ -7,5 +7,10 @@ # 数据卷(迁移时单独打包,不进 git) data/ +# ★ 2026-10-06 补:backup.sh 的产物落在 backups/,含 secrets 与完整 data 卷 +# (gitea.db / app.ini / runner 凭据)。原先漏了这一条,跑一次备份再 `git add .` +# 就会把凭据写进历史。 +backups/ + # write-server 运行时产物(若纳入) *.log diff --git a/gitea-backup/README.md b/deploy/gitea/README.md similarity index 83% rename from gitea-backup/README.md rename to deploy/gitea/README.md index 82319f03..25fc3b83 100644 --- a/gitea-backup/README.md +++ b/deploy/gitea/README.md @@ -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, 目标:**任何一台机器上,复制文件 + 一条命令就能拉起整套环境**,彻底告别「迁移要半天手工操作」。 diff --git a/gitea-backup/docker-compose.yml b/deploy/gitea/docker-compose.yml similarity index 94% rename from gitea-backup/docker-compose.yml rename to deploy/gitea/docker-compose.yml index e21ce83c..43b70839 100644 --- a/gitea-backup/docker-compose.yml +++ b/deploy/gitea/docker-compose.yml @@ -26,7 +26,11 @@ services: # 迁移:把旧机器 /opt/gitea/data 整个 rsync 到本机 ./data/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 restart: unless-stopped environment: diff --git a/gitea-backup/scripts/backup.sh b/deploy/gitea/scripts/backup.sh similarity index 100% rename from gitea-backup/scripts/backup.sh rename to deploy/gitea/scripts/backup.sh diff --git a/gitea-backup/scripts/restore.sh b/deploy/gitea/scripts/restore.sh similarity index 100% rename from gitea-backup/scripts/restore.sh rename to deploy/gitea/scripts/restore.sh diff --git a/gitea-backup/迁移前检查清单.md b/deploy/gitea/迁移前检查清单.md similarity index 93% rename from gitea-backup/迁移前检查清单.md rename to deploy/gitea/迁移前检查清单.md index 476e61e1..fd711f54 100644 --- a/gitea-backup/迁移前检查清单.md +++ b/deploy/gitea/迁移前检查清单.md @@ -1,5 +1,13 @@ # 迁移前检查清单(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 搬到**国内机**(当前中转机 > `119.29.215.187`,Ubuntu 24.04)。 > 下面是**照着做完再动手**的清单。带 ★ 的是会**直接卡住迁移**的硬伤。 diff --git a/CNB构建落地方案.md b/docs/CNB构建落地方案.md similarity index 99% rename from CNB构建落地方案.md rename to docs/CNB构建落地方案.md index 7b5a2995..58b8e0d3 100644 --- a/CNB构建落地方案.md +++ b/docs/CNB构建落地方案.md @@ -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 起在库 | 已跟踪 | | `.env` | `SILICONFLOW_API_KEY`、`ZHIPU_API_KEY` | 已跟踪 | -| `GITEA_SECRETS.md` | Gitea 相关凭据说明 | 已跟踪 | +| `docs/GITEA_SECRETS.md` | Gitea 相关凭据说明 | 已跟踪 | | `content/posts/2024/.../setup-secrets.png` | 疑似密钥配置截图 | 已跟踪 | **关于暴露面**:该仓一直是**私有**的(匿名 API 返回 404)。2026-10-06 账号被平台标记后 @@ -237,7 +237,7 @@ git config --global credential.helper manager # Windows 的 Git Credential Man 1. **CNB 仓库保持「私有」** —— 这些文件在私有仓里影响可控 2. **`git rm --cached` 停止继续跟踪**(历史里的删不掉,但至少不再新增): ```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.*` 规则 —— 它们失效的原因不是规则写错, 而是**忽略规则对「已跟踪」文件无效**,所以必须显式 `git rm --cached`。 diff --git a/GITEA_SECRETS.md b/docs/GITEA_SECRETS.md similarity index 100% rename from GITEA_SECRETS.md rename to docs/GITEA_SECRETS.md diff --git a/docs/Gitea迁移指南.md b/docs/Gitea迁移指南.md new file mode 100644 index 00000000..2116120e --- /dev/null +++ b/docs/Gitea迁移指南.md @@ -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='' \ + 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='' + +# ① .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 项**(线上那两处),否则容器会一直对着一个已经没了的辅仓报错。 diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 00000000..0ba8e8da --- /dev/null +++ b/docs/README.md @@ -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 使用) | diff --git a/docs/CLEANUP_GUIDE.md b/docs/archive/主题与内容/CLEANUP_GUIDE.md similarity index 93% rename from docs/CLEANUP_GUIDE.md rename to docs/archive/主题与内容/CLEANUP_GUIDE.md index b4fcbb4b..77c75dca 100644 --- a/docs/CLEANUP_GUIDE.md +++ b/docs/archive/主题与内容/CLEANUP_GUIDE.md @@ -1,3 +1,6 @@ +> 📦 **本文档已归档**(2026-10-06)。它记录的是**当时的工作过程与结论**,可能已被后续决策推翻。 +> **请勿据此判断当前架构** —— 现行架构唯一事实源是 [`架构总览.md`](../../../架构总览.md)。 + # 🧹 Ying主题文档清理指南 ## 📋 需要删除的文件(20个) diff --git a/docs/博客字体优化文章规划.md b/docs/archive/主题与内容/博客字体优化文章规划.md similarity index 96% rename from docs/博客字体优化文章规划.md rename to docs/archive/主题与内容/博客字体优化文章规划.md index f658f300..e74f2fbd 100644 --- a/docs/博客字体优化文章规划.md +++ b/docs/archive/主题与内容/博客字体优化文章规划.md @@ -1,3 +1,6 @@ +> 📦 **本文档已归档**(2026-10-06)。它记录的是**当时的工作过程与结论**,可能已被后续决策推翻。 +> **请勿据此判断当前架构** —— 现行架构唯一事实源是 [`架构总览.md`](../../../架构总览.md)。 + # 博客字体优化方案 - 文章规划 ## 📋 文章定位 diff --git a/docs/古风官职字符添加指南.md b/docs/archive/主题与内容/古风官职字符添加指南.md similarity index 91% rename from docs/古风官职字符添加指南.md rename to docs/archive/主题与内容/古风官职字符添加指南.md index 5ce735be..cd1ec5fd 100644 --- a/docs/古风官职字符添加指南.md +++ b/docs/archive/主题与内容/古风官职字符添加指南.md @@ -1,3 +1,6 @@ +> 📦 **本文档已归档**(2026-10-06)。它记录的是**当时的工作过程与结论**,可能已被后续决策推翻。 +> **请勿据此判断当前架构** —— 现行架构唯一事实源是 [`架构总览.md`](../../../架构总览.md)。 + # 📜 添加古风官职字符到字体子集 ## 📋 需要添加的字符 diff --git a/docs/性能优化文档/01-项目完成总结.md b/docs/archive/主题与内容/性能优化(历史)/01-项目完成总结.md similarity index 95% rename from docs/性能优化文档/01-项目完成总结.md rename to docs/archive/主题与内容/性能优化(历史)/01-项目完成总结.md index 82410b35..8020cd4b 100644 --- a/docs/性能优化文档/01-项目完成总结.md +++ b/docs/archive/主题与内容/性能优化(历史)/01-项目完成总结.md @@ -1,3 +1,6 @@ +> 📦 **本文档已归档**(2026-10-06)。它记录的是**当时的工作过程与结论**,可能已被后续决策推翻。 +> **请勿据此判断当前架构** —— 现行架构唯一事实源是 [`架构总览.md`](../../../../架构总览.md)。 + # 01-项目完成总结 **创建日期:** 2026-06-03 diff --git a/docs/性能优化文档/02-方案1完成总结.md b/docs/archive/主题与内容/性能优化(历史)/02-方案1完成总结.md similarity index 96% rename from docs/性能优化文档/02-方案1完成总结.md rename to docs/archive/主题与内容/性能优化(历史)/02-方案1完成总结.md index 25838a6e..7a4d0bc9 100644 --- a/docs/性能优化文档/02-方案1完成总结.md +++ b/docs/archive/主题与内容/性能优化(历史)/02-方案1完成总结.md @@ -1,3 +1,6 @@ +> 📦 **本文档已归档**(2026-10-06)。它记录的是**当时的工作过程与结论**,可能已被后续决策推翻。 +> **请勿据此判断当前架构** —— 现行架构唯一事实源是 [`架构总览.md`](../../../../架构总览.md)。 + # 02-方案1完成总结 **创建日期:** 2026-06-03 diff --git a/docs/性能优化文档/03-三步优化完整指南.md b/docs/archive/主题与内容/性能优化(历史)/03-三步优化完整指南.md similarity index 97% rename from docs/性能优化文档/03-三步优化完整指南.md rename to docs/archive/主题与内容/性能优化(历史)/03-三步优化完整指南.md index 99549b8b..8dfe8de2 100644 --- a/docs/性能优化文档/03-三步优化完整指南.md +++ b/docs/archive/主题与内容/性能优化(历史)/03-三步优化完整指南.md @@ -1,3 +1,6 @@ +> 📦 **本文档已归档**(2026-10-06)。它记录的是**当时的工作过程与结论**,可能已被后续决策推翻。 +> **请勿据此判断当前架构** —— 现行架构唯一事实源是 [`架构总览.md`](../../../../架构总览.md)。 + # 03-三步优化完整指南 **创建日期:** 2026-06-03 diff --git a/docs/性能优化文档/04-JS按需加载优化.md b/docs/archive/主题与内容/性能优化(历史)/04-JS按需加载优化.md similarity index 98% rename from docs/性能优化文档/04-JS按需加载优化.md rename to docs/archive/主题与内容/性能优化(历史)/04-JS按需加载优化.md index be92afc1..3ab62672 100644 --- a/docs/性能优化文档/04-JS按需加载优化.md +++ b/docs/archive/主题与内容/性能优化(历史)/04-JS按需加载优化.md @@ -1,3 +1,6 @@ +> 📦 **本文档已归档**(2026-10-06)。它记录的是**当时的工作过程与结论**,可能已被后续决策推翻。 +> **请勿据此判断当前架构** —— 现行架构唯一事实源是 [`架构总览.md`](../../../../架构总览.md)。 + # 04-JS按需加载优化 **创建日期:** 2026-06-03 diff --git a/docs/性能优化文档/05-PJAX适配说明.md b/docs/archive/主题与内容/性能优化(历史)/05-PJAX适配说明.md similarity index 96% rename from docs/性能优化文档/05-PJAX适配说明.md rename to docs/archive/主题与内容/性能优化(历史)/05-PJAX适配说明.md index 67b0c899..d8ebdf93 100644 --- a/docs/性能优化文档/05-PJAX适配说明.md +++ b/docs/archive/主题与内容/性能优化(历史)/05-PJAX适配说明.md @@ -1,3 +1,6 @@ +> 📦 **本文档已归档**(2026-10-06)。它记录的是**当时的工作过程与结论**,可能已被后续决策推翻。 +> **请勿据此判断当前架构** —— 现行架构唯一事实源是 [`架构总览.md`](../../../../架构总览.md)。 + # 05-PJAX适配说明 **创建日期:** 2026-06-03 diff --git a/docs/性能优化文档/06-PJAX修复总结.md b/docs/archive/主题与内容/性能优化(历史)/06-PJAX修复总结.md similarity index 94% rename from docs/性能优化文档/06-PJAX修复总结.md rename to docs/archive/主题与内容/性能优化(历史)/06-PJAX修复总结.md index e434d5bc..66b19e82 100644 --- a/docs/性能优化文档/06-PJAX修复总结.md +++ b/docs/archive/主题与内容/性能优化(历史)/06-PJAX修复总结.md @@ -1,3 +1,6 @@ +> 📦 **本文档已归档**(2026-10-06)。它记录的是**当时的工作过程与结论**,可能已被后续决策推翻。 +> **请勿据此判断当前架构** —— 现行架构唯一事实源是 [`架构总览.md`](../../../../架构总览.md)。 + # 06-PJAX修复总结 **创建日期:** 2026-06-03 diff --git a/docs/性能优化文档/07-字体子集化优化.md b/docs/archive/主题与内容/性能优化(历史)/07-字体子集化优化.md similarity index 94% rename from docs/性能优化文档/07-字体子集化优化.md rename to docs/archive/主题与内容/性能优化(历史)/07-字体子集化优化.md index 5707630e..6b1ad6b4 100644 --- a/docs/性能优化文档/07-字体子集化优化.md +++ b/docs/archive/主题与内容/性能优化(历史)/07-字体子集化优化.md @@ -1,3 +1,6 @@ +> 📦 **本文档已归档**(2026-10-06)。它记录的是**当时的工作过程与结论**,可能已被后续决策推翻。 +> **请勿据此判断当前架构** —— 现行架构唯一事实源是 [`架构总览.md`](../../../../架构总览.md)。 + # 07-字体子集化优化 **创建日期:** 2026-06-03 diff --git a/docs/性能优化文档/08-GitHub-Actions使用指南.md b/docs/archive/主题与内容/性能优化(历史)/08-GitHub-Actions使用指南.md similarity index 95% rename from docs/性能优化文档/08-GitHub-Actions使用指南.md rename to docs/archive/主题与内容/性能优化(历史)/08-GitHub-Actions使用指南.md index 9e7baa79..b10f9e9b 100644 --- a/docs/性能优化文档/08-GitHub-Actions使用指南.md +++ b/docs/archive/主题与内容/性能优化(历史)/08-GitHub-Actions使用指南.md @@ -1,3 +1,6 @@ +> 📦 **本文档已归档**(2026-10-06)。它记录的是**当时的工作过程与结论**,可能已被后续决策推翻。 +> **请勿据此判断当前架构** —— 现行架构唯一事实源是 [`架构总览.md`](../../../../架构总览.md)。 + # 08-GitHub-Actions使用指南 **创建日期:** 2026-06-03 diff --git a/docs/性能优化文档/09-Actions修复指南.md b/docs/archive/主题与内容/性能优化(历史)/09-Actions修复指南.md similarity index 92% rename from docs/性能优化文档/09-Actions修复指南.md rename to docs/archive/主题与内容/性能优化(历史)/09-Actions修复指南.md index c9a8f000..30ad72b5 100644 --- a/docs/性能优化文档/09-Actions修复指南.md +++ b/docs/archive/主题与内容/性能优化(历史)/09-Actions修复指南.md @@ -1,3 +1,6 @@ +> 📦 **本文档已归档**(2026-10-06)。它记录的是**当时的工作过程与结论**,可能已被后续决策推翻。 +> **请勿据此判断当前架构** —— 现行架构唯一事实源是 [`架构总览.md`](../../../../架构总览.md)。 + # 09-Actions修复指南 **创建日期:** 2026-06-03 diff --git a/docs/性能优化文档/10-提交指南.md b/docs/archive/主题与内容/性能优化(历史)/10-提交指南.md similarity index 95% rename from docs/性能优化文档/10-提交指南.md rename to docs/archive/主题与内容/性能优化(历史)/10-提交指南.md index ab196427..946c81d7 100644 --- a/docs/性能优化文档/10-提交指南.md +++ b/docs/archive/主题与内容/性能优化(历史)/10-提交指南.md @@ -1,3 +1,6 @@ +> 📦 **本文档已归档**(2026-10-06)。它记录的是**当时的工作过程与结论**,可能已被后续决策推翻。 +> **请勿据此判断当前架构** —— 现行架构唯一事实源是 [`架构总览.md`](../../../../架构总览.md)。 + # 10-提交指南 **创建日期:** 2026-06-03 diff --git a/docs/性能优化文档/11-JS优化测试指南.md b/docs/archive/主题与内容/性能优化(历史)/11-JS优化测试指南.md similarity index 93% rename from docs/性能优化文档/11-JS优化测试指南.md rename to docs/archive/主题与内容/性能优化(历史)/11-JS优化测试指南.md index ae4228e7..88d4a995 100644 --- a/docs/性能优化文档/11-JS优化测试指南.md +++ b/docs/archive/主题与内容/性能优化(历史)/11-JS优化测试指南.md @@ -1,3 +1,6 @@ +> 📦 **本文档已归档**(2026-10-06)。它记录的是**当时的工作过程与结论**,可能已被后续决策推翻。 +> **请勿据此判断当前架构** —— 现行架构唯一事实源是 [`架构总览.md`](../../../../架构总览.md)。 + # 11-JS优化测试指南 **创建日期:** 2026-06-03 diff --git a/docs/性能优化文档/12-字体优化测试指南.md b/docs/archive/主题与内容/性能优化(历史)/12-字体优化测试指南.md similarity index 93% rename from docs/性能优化文档/12-字体优化测试指南.md rename to docs/archive/主题与内容/性能优化(历史)/12-字体优化测试指南.md index a0167614..8d4052cd 100644 --- a/docs/性能优化文档/12-字体优化测试指南.md +++ b/docs/archive/主题与内容/性能优化(历史)/12-字体优化测试指南.md @@ -1,3 +1,6 @@ +> 📦 **本文档已归档**(2026-10-06)。它记录的是**当时的工作过程与结论**,可能已被后续决策推翻。 +> **请勿据此判断当前架构** —— 现行架构唯一事实源是 [`架构总览.md`](../../../../架构总览.md)。 + # 12-字体优化测试指南 **创建日期:** 2026-06-03 diff --git a/docs/性能优化文档/13-主题全面优化分析.md b/docs/archive/主题与内容/性能优化(历史)/13-主题全面优化分析.md similarity index 94% rename from docs/性能优化文档/13-主题全面优化分析.md rename to docs/archive/主题与内容/性能优化(历史)/13-主题全面优化分析.md index 97163213..4d05a236 100644 --- a/docs/性能优化文档/13-主题全面优化分析.md +++ b/docs/archive/主题与内容/性能优化(历史)/13-主题全面优化分析.md @@ -1,3 +1,6 @@ +> 📦 **本文档已归档**(2026-10-06)。它记录的是**当时的工作过程与结论**,可能已被后续决策推翻。 +> **请勿据此判断当前架构** —— 现行架构唯一事实源是 [`架构总览.md`](../../../../架构总览.md)。 + # 13-主题全面优化分析 **创建日期:** 2026-06-03 diff --git a/docs/性能优化文档/14-JS优化最终方案.md b/docs/archive/主题与内容/性能优化(历史)/14-JS优化最终方案.md similarity index 93% rename from docs/性能优化文档/14-JS优化最终方案.md rename to docs/archive/主题与内容/性能优化(历史)/14-JS优化最终方案.md index 6da505ef..35c545b3 100644 --- a/docs/性能优化文档/14-JS优化最终方案.md +++ b/docs/archive/主题与内容/性能优化(历史)/14-JS优化最终方案.md @@ -1,3 +1,6 @@ +> 📦 **本文档已归档**(2026-10-06)。它记录的是**当时的工作过程与结论**,可能已被后续决策推翻。 +> **请勿据此判断当前架构** —— 现行架构唯一事实源是 [`架构总览.md`](../../../../架构总览.md)。 + # 14-JS优化最终方案 **创建日期:** 2026-06-03 diff --git a/docs/性能优化文档/15-字体优化手动指南.md b/docs/archive/主题与内容/性能优化(历史)/15-字体优化手动指南.md similarity index 93% rename from docs/性能优化文档/15-字体优化手动指南.md rename to docs/archive/主题与内容/性能优化(历史)/15-字体优化手动指南.md index 1f5f24b0..2695c6a1 100644 --- a/docs/性能优化文档/15-字体优化手动指南.md +++ b/docs/archive/主题与内容/性能优化(历史)/15-字体优化手动指南.md @@ -1,3 +1,6 @@ +> 📦 **本文档已归档**(2026-10-06)。它记录的是**当时的工作过程与结论**,可能已被后续决策推翻。 +> **请勿据此判断当前架构** —— 现行架构唯一事实源是 [`架构总览.md`](../../../../架构总览.md)。 + # 15-字体优化手动指南 **创建日期:** 2026-06-03 diff --git a/docs/性能优化文档/16-实施总结报告.md b/docs/archive/主题与内容/性能优化(历史)/16-实施总结报告.md similarity index 95% rename from docs/性能优化文档/16-实施总结报告.md rename to docs/archive/主题与内容/性能优化(历史)/16-实施总结报告.md index df9bfd50..b2571f3a 100644 --- a/docs/性能优化文档/16-实施总结报告.md +++ b/docs/archive/主题与内容/性能优化(历史)/16-实施总结报告.md @@ -1,3 +1,6 @@ +> 📦 **本文档已归档**(2026-10-06)。它记录的是**当时的工作过程与结论**,可能已被后续决策推翻。 +> **请勿据此判断当前架构** —— 现行架构唯一事实源是 [`架构总览.md`](../../../../架构总览.md)。 + # 16-实施总结报告 **创建日期:** 2026-06-03 diff --git a/docs/性能优化文档/Markdown表格样式使用指南.md b/docs/archive/主题与内容/性能优化(历史)/Markdown表格样式使用指南.md similarity index 97% rename from docs/性能优化文档/Markdown表格样式使用指南.md rename to docs/archive/主题与内容/性能优化(历史)/Markdown表格样式使用指南.md index 66d03d9b..984c159a 100644 --- a/docs/性能优化文档/Markdown表格样式使用指南.md +++ b/docs/archive/主题与内容/性能优化(历史)/Markdown表格样式使用指南.md @@ -1,3 +1,6 @@ +> 📦 **本文档已归档**(2026-10-06)。它记录的是**当时的工作过程与结论**,可能已被后续决策推翻。 +> **请勿据此判断当前架构** —— 现行架构唯一事实源是 [`架构总览.md`](../../../../架构总览.md)。 + # Ying主题 Markdown 表格样式使用指南 **创建日期:** 2026-06-03 diff --git a/docs/性能优化文档/README.md b/docs/archive/主题与内容/性能优化(历史)/README.md similarity index 95% rename from docs/性能优化文档/README.md rename to docs/archive/主题与内容/性能优化(历史)/README.md index fbee8e01..140f0b31 100644 --- a/docs/性能优化文档/README.md +++ b/docs/archive/主题与内容/性能优化(历史)/README.md @@ -1,3 +1,6 @@ +> 📦 **本文档已归档**(2026-10-06)。它记录的是**当时的工作过程与结论**,可能已被后续决策推翻。 +> **请勿据此判断当前架构** —— 现行架构唯一事实源是 [`架构总览.md`](../../../../架构总览.md)。 + # 📚 性能优化文档索引 **整理日期:** 2026-06-03 diff --git a/docs/深色模式表格修复指南.md b/docs/archive/主题与内容/深色模式表格修复指南.md similarity index 95% rename from docs/深色模式表格修复指南.md rename to docs/archive/主题与内容/深色模式表格修复指南.md index 9ecb9555..a3a395d0 100644 --- a/docs/深色模式表格修复指南.md +++ b/docs/archive/主题与内容/深色模式表格修复指南.md @@ -1,3 +1,6 @@ +> 📦 **本文档已归档**(2026-10-06)。它记录的是**当时的工作过程与结论**,可能已被后续决策推翻。 +> **请勿据此判断当前架构** —— 现行架构唯一事实源是 [`架构总览.md`](../../../架构总览.md)。 + # 深色模式表格样式修复指南 ## 🔍 问题诊断 diff --git a/在线编辑器集成评估.md b/docs/archive/功能与修复/在线编辑器集成评估.md similarity index 96% rename from 在线编辑器集成评估.md rename to docs/archive/功能与修复/在线编辑器集成评估.md index 0f6222a4..164b8cbc 100644 --- a/在线编辑器集成评估.md +++ b/docs/archive/功能与修复/在线编辑器集成评估.md @@ -1,3 +1,6 @@ +> 📦 **本文档已归档**(2026-10-06)。它记录的是**当时的评估与方案**,其中的结论可能已被后续决策推翻。 +> **请勿据此判断当前架构** —— 现行架构唯一事实源是 [`架构总览.md`](../../../架构总览.md)。 + # 在线编辑文章 · 集成到 api.200181.xyz/admin > 日期:2026-10-04(定稿) diff --git a/评论加载优化方案.md b/docs/archive/功能与修复/评论加载优化方案.md similarity index 98% rename from 评论加载优化方案.md rename to docs/archive/功能与修复/评论加载优化方案.md index 93b169e0..7376a6ae 100644 --- a/评论加载优化方案.md +++ b/docs/archive/功能与修复/评论加载优化方案.md @@ -1,3 +1,6 @@ +> 📦 **本文档已归档**(2026-10-06)。它记录的是**当时的评估与方案**,其中的结论可能已被后续决策推翻。 +> **请勿据此判断当前架构** —— 现行架构唯一事实源是 [`架构总览.md`](../../../架构总览.md)。 + # 评论加载优化方案(Cloudflare 免费版) > 起因:读者侧「评论加载太慢」。 diff --git a/评论孤儿修复方案-2026-10-06.md b/docs/archive/功能与修复/评论孤儿修复方案-2026-10-06.md similarity index 95% rename from 评论孤儿修复方案-2026-10-06.md rename to docs/archive/功能与修复/评论孤儿修复方案-2026-10-06.md index 95497c2e..34b37666 100644 --- a/评论孤儿修复方案-2026-10-06.md +++ b/docs/archive/功能与修复/评论孤儿修复方案-2026-10-06.md @@ -1,3 +1,6 @@ +> 📦 **本文档已归档**(2026-10-06)。它记录的是**当时的评估与方案**,其中的结论可能已被后续决策推翻。 +> **请勿据此判断当前架构** —— 现行架构唯一事实源是 [`架构总览.md`](../../../架构总览.md)。 + # 评论区孤儿评论修复方案(2026-10-06) > ## ✅ 状态:**已执行完成**(2026-10-06 12:2x) diff --git a/诊断报告-2026-10-06.md b/docs/archive/功能与修复/诊断报告-2026-10-06.md similarity index 98% rename from 诊断报告-2026-10-06.md rename to docs/archive/功能与修复/诊断报告-2026-10-06.md index ebaf9a81..e3a8fca4 100644 --- a/诊断报告-2026-10-06.md +++ b/docs/archive/功能与修复/诊断报告-2026-10-06.md @@ -1,3 +1,6 @@ +> 📦 **本文档已归档**(2026-10-06)。它记录的是**当时的评估与方案**,其中的结论可能已被后续决策推翻。 +> **请勿据此判断当前架构** —— 现行架构唯一事实源是 [`架构总览.md`](../../../架构总览.md)。 + # 四问诊断报告(2026-10-06) 一次性回答四个问题:CDN 刷新、KV 配额、D1 评论对账、certimate 迁移。 diff --git a/EdgeOne双区域方案评估.md b/docs/archive/平台与选型/EdgeOne双区域方案评估.md similarity index 97% rename from EdgeOne双区域方案评估.md rename to docs/archive/平台与选型/EdgeOne双区域方案评估.md index 2302f92d..b4f4558c 100644 --- a/EdgeOne双区域方案评估.md +++ b/docs/archive/平台与选型/EdgeOne双区域方案评估.md @@ -1,3 +1,6 @@ +> 📦 **本文档已归档**(2026-10-06)。它记录的是**当时的评估与方案**,其中的结论可能已被后续决策推翻。 +> **请勿据此判断当前架构** —— 现行架构唯一事实源是 [`架构总览.md`](../../../架构总览.md)。 + # EdgeOne 双区域方案评估 > 2026-10-04 · 针对「境外用 EdgeOne 国际站、境内改用 EdgeOne 国内站」的构想 diff --git a/Gitee方案评估.md b/docs/archive/平台与选型/Gitee方案评估.md similarity index 96% rename from Gitee方案评估.md rename to docs/archive/平台与选型/Gitee方案评估.md index cab2b5a5..8a98784b 100644 --- a/Gitee方案评估.md +++ b/docs/archive/平台与选型/Gitee方案评估.md @@ -1,3 +1,6 @@ +> 📦 **本文档已归档**(2026-10-06)。它记录的是**当时的评估与方案**,其中的结论可能已被后续决策推翻。 +> **请勿据此判断当前架构** —— 现行架构唯一事实源是 [`架构总览.md`](../../../架构总览.md)。 + # Gitee 方案评估 > 回答:**「Gitee 算不算一个替代方案?」** diff --git a/代码源与构建平台选型.md b/docs/archive/平台与选型/代码源与构建平台选型.md similarity index 97% rename from 代码源与构建平台选型.md rename to docs/archive/平台与选型/代码源与构建平台选型.md index b509bb67..6d3496f0 100644 --- a/代码源与构建平台选型.md +++ b/docs/archive/平台与选型/代码源与构建平台选型.md @@ -1,3 +1,6 @@ +> 📦 **本文档已归档**(2026-10-06)。它记录的是**当时的评估与方案**,其中的结论可能已被后续决策推翻。 +> **请勿据此判断当前架构** —— 现行架构唯一事实源是 [`架构总览.md`](../../../架构总览.md)。 + # 代码源与构建平台选型 > 回答的问题:**「想简化是不是只能走 EdgeOne?」** diff --git a/砍COS改造步骤.md b/docs/archive/平台与选型/砍COS改造步骤.md similarity index 97% rename from 砍COS改造步骤.md rename to docs/archive/平台与选型/砍COS改造步骤.md index 4732ba8a..0b4453a0 100644 --- a/砍COS改造步骤.md +++ b/docs/archive/平台与选型/砍COS改造步骤.md @@ -1,3 +1,6 @@ +> 📦 **本文档已归档**(2026-10-06)。它记录的是**当时的评估与方案**,其中的结论可能已被后续决策推翻。 +> **请勿据此判断当前架构** —— 现行架构唯一事实源是 [`架构总览.md`](../../../架构总览.md)。 + # 砍掉腾讯云 COS 中转层 —— 完整改造步骤 > 目标:把「build → COS → 中转机 → 又拍云 → 多吉云」这条绕路, diff --git a/精简方案-只留CF和Hugo.md b/docs/archive/平台与选型/精简方案-只留CF和Hugo.md similarity index 97% rename from 精简方案-只留CF和Hugo.md rename to docs/archive/平台与选型/精简方案-只留CF和Hugo.md index 919537d2..93b1a741 100644 --- a/精简方案-只留CF和Hugo.md +++ b/docs/archive/平台与选型/精简方案-只留CF和Hugo.md @@ -1,3 +1,6 @@ +> 📦 **本文档已归档**(2026-10-06)。它记录的是**当时的评估与方案**,其中的结论可能已被后续决策推翻。 +> **请勿据此判断当前架构** —— 现行架构唯一事实源是 [`架构总览.md`](../../../架构总览.md)。 + # 精简方案:只留 Cloudflare + Hugo > 2026-10-04 diff --git a/阿里云ESA评估.md b/docs/archive/平台与选型/阿里云ESA评估.md similarity index 97% rename from 阿里云ESA评估.md rename to docs/archive/平台与选型/阿里云ESA评估.md index 6120692f..f4e60931 100644 --- a/阿里云ESA评估.md +++ b/docs/archive/平台与选型/阿里云ESA评估.md @@ -1,3 +1,6 @@ +> 📦 **本文档已归档**(2026-10-06)。它记录的是**当时的评估与方案**,其中的结论可能已被后续决策推翻。 +> **请勿据此判断当前架构** —— 现行架构唯一事实源是 [`架构总览.md`](../../../架构总览.md)。 + # 阿里云 ESA 评估(对比 EdgeOne) > 2026-10-04 · 问题:「阿里云也有个跟 EdgeOne 很像的服务,能不能考虑一下?」 diff --git a/docs/架构精简候选.md b/docs/架构精简候选.md new file mode 100644 index 00000000..d1651eb3 --- /dev/null +++ b/docs/架构精简候选.md @@ -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)。 +> **这才是「感觉复杂」的真正解药 —— 减的是「要记得它」的东西,不是「存在于架构图里」的东西。** diff --git a/函数版证书管家-方案.md b/docs/证书管家.md similarity index 96% rename from 函数版证书管家-方案.md rename to docs/证书管家.md index a980ce62..8434031b 100644 --- a/函数版证书管家-方案.md +++ b/docs/证书管家.md @@ -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 这个服务精简掉。 +> —— ⚠️ 该目标**已被 §9 推翻**:Worker 免费版 CPU 硬顶 10ms/请求,签发跑不动,改由国内机承担。 -**已确认的决策(2026-10-06)** +**当时确认的决策(2026-10-06)** | 项 | 决定 | |---|---| diff --git a/scripts/backup-bundle.mjs b/scripts/backup-bundle.mjs index f3aa7012..24c2c188 100644 --- a/scripts/backup-bundle.mjs +++ b/scripts/backup-bundle.mjs @@ -7,7 +7,7 @@ * (表面成功、实际随机损坏,可能几个月后才发现)。bundle 是单文件顺序写,安全。 * * 为什么默认加密: - * 本仓库历史里含 .env、TLS 私钥、GITEA_SECRETS.md。目标介质是手机内部存储, + * 本仓库历史里含 .env、TLS 私钥、docs/GITEA_SECRETS.md。目标介质是手机内部存储, * 未加密等于把密钥明文放在一台可能被刷机/丢失/他人访问的设备上。 * * 为什么不用 gpg: diff --git a/架构总览.md b/架构总览.md index c24846b7..d3b2935c 100644 --- a/架构总览.md +++ b/架构总览.md @@ -1,28 +1,31 @@ # 优世界博客 · 架构总览 -> 更新时间:2026-10-04(CNB 迁移完成当日) +> 更新时间:2026-10-06 > 状态:**迁移已落地并跑通**(四线路全绿,单次发布约 3.5 分钟) -> 本文档只描述**现状**;迁移前的复杂度审计与选型过程见文末「相关文档」。 +> 本文档只描述**现状**;决策期的一次性评估与已完结方案见 [`docs/archive/`](docs/archive/)。 +> 文档地图见 [`docs/README.md`](docs/README.md)。 --- ## 0. 一句话 -四个子系统,一条 **3 步**的托管发布链路。构建与发布已从「自建 Gitea + act_runner + 广州中转机」迁到 -**腾讯云 CNB(cnb.cool)** —— **需要自己运维的机器从 3 台降到 0 台**。 +**五个子系统**,一条 **3 步**的托管发布链路。构建与发布已从「自建 Gitea + act_runner + 广州中转机」迁到 +**腾讯云 CNB(cnb.cool)** —— 发布链路上**需要自己运维的机器从 3 台降到 0 台** +(另有一台国内机跑写作后台与证书签发,但都不在构建链路里)。 --- ## 1. 全景 -### 1.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(**托管**) | **新建,已跑通** | +| **3** | **写作系统** | `write-server/`(Next.js 16,`post.usj.cc`)
`write/`(本地 Windows 前端)
`editor-api/`(国内机轻量后端,实为线上那条发布入口) | 独立 Docker 主机/本机/国内机 | 可用(两套前端功能重叠) | +| **4** | **发布基础设施** | **CNB 流水线**(`.cnb.yml`)+ 又拍云 + 多吉云 + EdgeOne | 腾讯云 CNB(**托管**) | **已跑通** | +| **5** | **证书系统** | 证书管家(自研):ACME 签发 + DNS-01 + 多目标部署(多吉云 / 1Panel) | **国内机 Docker `cn-certkeeper`**(签发+部署)
+ CF Worker(**只读**:监控/后台/探针) | ✅ 已上线,每日 04:10 自动续期(详见 §5.7) | ### 1.2 服务与地址地图 @@ -38,6 +41,8 @@ | **国内加速** | 多吉云 CDN | 回源又拍云 | | **境外线路** | EdgeOne Pages(项目 `hugo-blog`,`--area overseas`) | 腾讯 EdgeOne 国际站 | | **评论后端** | `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) | > 关键点:境内、境外仍是**两条独立线路**,但**由同一条流水线一次推完** —— @@ -77,7 +82,7 @@ --- -## 3. 流水线细节(`.cnb.yml`,284 行) +## 3. 流水线细节(`.cnb.yml`,337 行) | 触发 | 条件 | 说明 | |---|---|---| @@ -315,7 +320,7 @@ GitHub 那次 AUP 清空就是活证。自建 Gitea 是唯一「不受第三方 把 bare repo 挂上去直接 `git push` 会让对象写坏 —— 表面成功、实际随机损坏, 可能几个月后才发现。bundle 是**单文件顺序写**,没有这个问题。 -**为什么加密**:本仓库历史里含 `.env`、TLS 私钥、`GITEA_SECRETS.md`。 +**为什么加密**:本仓库历史里含 `.env`、TLS 私钥、`docs/GITEA_SECRETS.md`。 介质是一台随身设备的内部存储,明文等于把密钥放在可能丢失 / 刷机 / 送修的设备上。 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. 遗留待办 | # | 项 | 说明 | @@ -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) | | 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 可自行排错 | -| 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 化 + 补上备份脚本说明) | -| 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 端口**未暴露到公网** | | 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 追平 | +| 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/` 目录空、源站握手失败)。
(附带澄清:`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` — 迁移实施方案与实测数据 -- `代码源与构建平台选型.md` — 平台对比(CNB / Gitee / GitLab / EdgeOne / 阿里云 ESA) -- `砍COS改造步骤.md` — COS 下线记录 -- `EdgeOne双区域方案评估.md`、`Gitee方案评估.md`、`阿里云ESA评估.md`、`精简方案-只留CF和Hugo.md` — 决策期评估 +文档只有两个入口在根目录(`README.md`、本文);其余在 `docs/`,一次性的评估与已完结方案在 `docs/archive/`。 +完整地图见 [`docs/README.md`](docs/README.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`、 `scripts/send_mail.js`、`scripts/refresh_cdn.js`、`scripts/setup-cnb-remotes.sh`、