# Gitea 可移植部署包 把博客相关的**代码托管(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` 可以删掉。