Files
blog/deploy/gitea/迁移前检查清单.md
T
zqlit 7abef4ac13 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 迁移死线」两节;证书管家节补实测与遗留。
2026-10-06 22:27:36 +08:00

174 lines
7.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 迁移前检查清单(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)。
> 下面是**照着做完再动手**的清单。带 ★ 的是会**直接卡住迁移**的硬伤。
---
## 一、★ 硬伤:compose 里 pin 的 Gitea 镜像 tag 不存在
`docker-compose.yml:29`
```yaml
image: gitea/gitea:1.28.0-rootless # ❌ 这个 tag 不存在
```
**原因**:**Gitea 28.0.0 起去掉了历史 `1.` 前缀** —— 原本的 `1.28.0` 现在就叫 `28.0.0`。
境外那台 `/api/v1/version` 实测返回 `{"version":"28.0.0"}`。
**已在目标机实测(`docker pull`,决定性)**:
| 镜像 tag | 结果 |
|---|---|
| `gitea/gitea:1.28.0-rootless` | ❌ `not found` |
| `gitea/gitea:28.0.0-rootless` | ✅ 可拉取 |
| `gitea/gitea:latest` | ✅ 可拉取 |
| `gitea/act_runner:0.2.11` | ✅ 可拉取 |
| `gitea/act_runner:4.0.0` | ❌ `not found` |
**改**:`gitea/gitea:28.0.0-rootless`(建议 pin 死版本,别用 `latest`,免得下次再被动升级)。
`28.0.0-rootless` 与 `latest` **已经拉到目标机上了**,迁移时省一次等待。
---
## 二、★ `.gitignore` 没忽略 `backups/`
`scripts/backup.sh` 的产物落在 `backups/`:
```
backups/gitea-dump-<时间戳>.zip # gitea dump,含 secrets(加密但仍是敏感物)
backups/data-<时间戳>.tar.gz # 完整 data 卷:gitea.db / app.ini / runner 凭据 / upyun 目录
```
而 `.gitignore` 里**只有** `.env` / `data/` / `*.log` —— **没有 `backups/`**。
跑一次备份,这两个文件就出现在仓库里了,`git add .` 一下全进历史。
**改**:`.gitignore` 加一行 `backups/`。
---
## 三、凭据散落情况(迁移时容易漏)
| 位置 | 内容 | 风险 |
|---|---|---|
| `gitea-backup/.env.example` | `UPYUN_BUCKET=imzql`、`UPYUN_OPERATOR=1770186415` | **真实值**,不是占位符 |
| `write-server/nginx/ssl/privkey.pem` | SSL 私钥 | **已被 git 跟踪**(仓库历史里有) |
| 中转机 `/opt/upyun-sync/sync.sh` | 又拍云密码 + 多吉云 AK/SK **明文硬编码** | 该文件会被整体搬进 `data/upyun-sync/` |
| 本地 `.git/config` 的 `gitea` remote | `http://用户:密码@...` | 明文写在 remote URL 里 |
容器化后 `upyun-sync` 是用 `.env` 注入凭据的,但 `sync.sh` 里**又硬编码了一份** ——
两套并存,容易改一处漏一处。建议统一成只读环境变量。
---
## 四、容器网络:脚本要走服务名,别绕公网
`upyun-sync` 容器与 `gitea` 同在 `gitea-net` 这个 bridge 网络里。
如果脚本里继续用 `https://gitea.usj.cc`,会**出到公网 DNS 再绕回来**(还可能撞上 CDN)。
**改**:`sync.sh` 里 `GITEA` 默认值改成 `http://gitea:3000`(compose 服务名 + 容器内端口)。
脚本已经写成 `GITEA="${GITEA:-...}"`,用环境变量覆盖即可,不必改脚本。
---
## 五、反向代理要补一条
目标机上 **OpenResty 已占用 80/443**(1Panel 托管的站点)。
`gitea` 容器映射的是宿主 `3001`(HTTP)/ `2222`(SSH),**这两个端口在目标机是空闲的**
(已实测)。
要让 `https://gitea.usj.cc` 生效,需在 1Panel 的 OpenResty 里加一个反代站点
→ `127.0.0.1:3001`,并配好证书。DNS 也要把 `gitea.usj.cc` 指到目标机。
> ⚠️ Gitea 28 起**不再读取 `[server] DOMAIN`**,实例域名(含默认 SSH 域名)全部来自 `ROOT_URL`。
> compose 里两个都填了,所以没问题;但改域名时**只需改 `ROOT_URL`**。
---
## 六、资源评估:内存是短板
目标机现状(实测):
| 项 | 值 |
|---|---|
| CPU | **2 核** |
| 内存 | **1.9 G**(已用 665 M,free 126 M,buff/cache 1369 M) |
| **Swap** | 1987 M,**已用 832 M** ← 已经在吃 swap |
| 磁盘 | 50 G,已用 17 G,**剩 31 G** |
| 已在跑 | 1Panel(3721)、mysql 8.4、certimate、OpenResty(80/443)、frps、alist、vaultwarden |
要再加进:**Gitea + act_runner + 一次 hugo 构建**(构建要跑 npm ci、hugo --minify、
打包 ~380 MB 产物)。这台机器现在就已经在换页了,**2 G 内存很紧**。
磁盘侧估算(够用但不宽裕):Gitea 数据(仓库全历史,含大量图片)+ artifact
(~380 MB/次 × 保留 7 天)+ `data/upyun-sync/` 里的产物副本(~750 M)≈ **6–10 G**。
**建议**:迁移前把内存加到 **4 G**;或将 `mysql` 等非必需容器停掉腾资源。
---
## 七、★ 迁移后会变的架构(决定要不要保留中转机)
`deploy.yml` 里 `Upload to UpYun` 那一步现在写死 `if: false`,注释原话:
> 国内线路由腾讯云广州中转机兜底……**将来若把 runner 挪到国内,把下面的 `if: false` 删掉即可恢复。**
也就是说 **runner 一旦在国内,又拍云直传就可行**(当初失败是因为境外出口被 GSLB 调度到坏节点)。
那时整条链路可以简化成:
```
runner(国内) → build → 又拍云直传 → purge → 多吉云刷新
```
**「中转机 + sync.sh + Gitea artifact 给中转机」这一层就可以整个删掉。**
但有两个代价要权衡:
1. **EdgeOne Pages 部署会变成跨境**(境内 runner → 境外 EdgeOne)。目前 runner 在境外,
这一步是零跨境的。需要实测耗时是否可接受。
2. 又拍云直传要补 **`upx purge`**(现在这一步在 sync.sh 里,deploy.yml 的直传步骤没有)。
多吉云刷新 finalize 里已有(`upyun_status == success` 时才刷)。
> 建议:**先按「保留 artifact 传递」把迁移做完**(artifact 在 build → deploy-edgeone
> 之间是必需的,无论如何都要留),跑通之后再单独决定要不要砍中转机。
> 别把「迁移」和「架构简化」两件事混在一次变更里。
---
## 八、迁移顺序(照做)
1. **先修本文档第一节的镜像 tag**,`docker compose up` 才不会卡在第一屏
2. 补 `.gitignore` 的 `backups/`
3. 目标机:`mkdir -p data/gitea data/runner data/upyun-sync`
4. 旧机器 rsync 数据(沿用 README 的路径):
- `/opt/gitea/data/` → `data/gitea/`
- `/opt/upyun-sync/` → `data/upyun-sync/`
- ⚠️ 用 `rsync -a` 保留属主;Gitea rootless 镜像按 **uid/gid 1000** 跑,
属主不对会起不来
5. `cp .env.example .env` 并填好(`ROOT_URL` 必填)
6. **停掉 1Panel 的计划任务「又拍云同步(国内中转)」`id=15`** —— 否则
容器版 `upyun-sync` 与它**同时**同步,双写又拍云
7. `docker compose up -d` → `docker compose ps` 三个服务 healthy
8. Gitea 后台重新拿 runner 注册 token → 填 `.env` → `up -d --force-recreate runner`
9. OpenResty 加反代站点 + DNS 切 `gitea.usj.cc`
10. 验证:`git push` 一次,看 Actions 是否正常构建部署
---
## 九、尚未核实的两点
- `scripts/backup.sh` 里 `gitea dump --config ... -R -S`:这两个参数的语义需核对
(担心是「跳过仓库」之类,导致 dump 不完整)。**建议实跑一次备份,检查 zip 里有没有
`repositories/`**。
- 旧机器上的 `docker-compose.yml` 里 Gitea 用的到底是哪个 tag(`latest` 还是 pin 的版本)——
直接把 `:latest` 的数据目录搬到一个 pin 死的旧版本上会有兼容风险,**版本必须 ≥ 旧机**。