Files
blog/deploy/gitea/README.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

149 lines
5.6 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.
# 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,
目标:**任何一台机器上,复制文件 + 一条命令就能拉起整套环境**,彻底告别「迁移要半天手工操作」。
> 背景:境外那台 2C2G 服务器(23.254.236.47)十一月到期,且后续可能没时间慢慢迁移。
> 这个部署包就是把「迁移成本」从「半天手工」压到「copy + up」。
---
## 包含哪些服务
| 服务 | 镜像 | 说明 |
|---|---|---|
| **gitea** | `gitea/gitea:1.28.0-rootless` | 代码托管 + CI 调度。SQLite 单文件,数据全在 `data/gitea/` |
| **runner** | `gitea/act_runner:0.2.11` | Gitea Actions 执行器,跑博客构建/部署 |
| **upyun-sync** | `alpine:3.20` | 又拍云同步(原 1Panel 计划任务「又拍云同步(国内中转)」,容器化后不再依赖面板) |
| write-server | (可选,默认注释) | 写作后台,源码在仓库根 `write-server/` |
**不在本部署包里的**(它们有自己的形态,不适合塞进 compose):
| 服务 | 形态 | 为什么不在 |
|---|---|---|
| 博客站点 | 静态文件 + CDN | 构建产物由 runner 推给 EdgeOne / 又拍云,不是常驻服务 |
| 评论后端 artalk-cf | Cloudflare Workers | 无服务器,`wrangler deploy` 部署,见 `blog-admin/` |
| write-server | 独立 Docker | 可选纳入,见 compose 注释 |
---
## 目录结构
```
gitea-backup/
├── docker-compose.yml # 核心:三个服务 + 网络
├── .env.example # 变量模板(复制成 .env)
├── .gitignore # 忽略 .env 和 data/
├── README.md # 本文档
├── scripts/
│ ├── backup.sh # 一键备份:gitea dump + 打包 data 卷
│ └── restore.sh # 一键恢复
└── data/ # 数据卷(git 忽略,迁移时打包)
├── gitea/ # Gitea 数据(gitea.db + app.ini + 仓库)
├── runner/ # act_runner 配置
└── upyun-sync/ # 同步脚本 + upx + cos_sign.py
```
---
## 首次部署(新机器)
### 1. 准备代码和数据
```bash
# 克隆仓库(含 gitea-backup)
git clone <你的仓库> && cd <仓库>/gitea-backup
# 迁移数据:从旧机器把数据卷 rsync 过来
# (旧机器 23.254.236.47 上)
rsync -av --progress /opt/gitea/data/ 新机器:/path/to/gitea-backup/data/gitea/
# 又拍云同步目录同理:
rsync -av --progress /opt/upyun-sync/ 新机器:/path/to/gitea-backup/data/upyun-sync/
```
### 2. 配置
```bash
cp .env.example .env
# 编辑 .env:填域名、端口、又拍云密码
```
### 3. 启动
```bash
docker compose up -d
docker compose ps # 确认三个服务都 healthy/running
```
### 4. 注册 runner(首次必做)
```bash
# 到 Gitea 后台:站点管理 → Actions → Runners → 创建 runner → 复制注册 token
# 把 token 填进 .env 的 RUNNER_REGISTRATION_TOKEN,然后:
docker compose up -d --force-recreate runner
# 回到后台确认 runner 已在线(绿色)
```
---
## 备份
```bash
bash scripts/backup.sh
# 产物:backups/gitea-dump-<时间戳>.zip(含 gitea dump + app.ini)
# backups/data-<时间戳>.tar.gz(含完整 data 卷)
```
`gitea dump` 会导出仓库 + 用户 + 配置 + secrets(加密),是最完整的一站式备份。
## 恢复(灾难场景)
```bash
bash scripts/restore.sh backups/gitea-dump-<时间戳>.zip
# 或手动:把 data 卷解回 data/,然后 docker compose up -d
```
---
## 从旧机器迁移的完整清单(十一月到期前照着做)
1. 新机器装 docker + docker compose
2. `rsync` 旧机器 `/opt/gitea/data` → 新机器 `data/gitea/`
3. `rsync` 旧机器 `/opt/upyun-sync` → 新机器 `data/upyun-sync/`
4. `cp .env.example .env` 并填好
5. `docker compose up -d`
6. 后台重新注册 runner(token 会变)
7. DNS 把 `gitea.usj.cc` 指向新机器 IP
8. 验证:`git push` 一次,看 Actions 是否正常构建部署
> ⚠️ 第 6 步 runner token 每次重新注册都会变,旧 token 作废,必须在后台重新拿。
---
## 关于「又拍云同步」的容器化说明
原 1Panel 计划任务是 `bash /opt/upyun-sync/sync.sh`,每分钟跑一次,负责:
从 COS 拉构建产物 → 解压 → `upx sync` 到又拍云 → purge → 刷多吉云。
容器化后逻辑不变,只是**用 `while sleep 60` 循环替代了 cron**(不再依赖 1Panel)。
注意:`sync.sh` 里如果还引用 COS(`cos_sign.py` 签 COS 地址),说明 COS 还没砍;
如果已改为「拉 Gitea artifact」,则 `cos_sign.py` 可以删掉。