Files
jiu/docs/deployment-nas-gitea.md
wangjia aa7099ba94 feat(devops): 发版拆分为 client/site/server 三条独立流水线
将单一 CI/CD 流水线拆成三条互不影响的发布流水线,各有 tag 前缀、独立版本
序列与独立 CHANGELOG:

- client(client-v*):Flutter 全平台 + version.yaml 自更新清单
- site(site-v*):web/ Eleventy 营销站,不含 web 版 app
- server(server-v*):backend Go 服务 + 共享基建 nginx/systemd

新增 3 个 workflow(deploy-client/site/server.yml)替换 deploy.yml;CI 脚本
按 part 拆分为 compile-/release-/deploy-{client,site,server}.sh,抽出公共函数
lib-forgejo.sh;compile-{macos,android,ios,windows}.sh 改去 client-v 前缀;
manual.yml 按前缀路由回滚。

跨流水线解耦:version.yaml 归 client,后端每请求实时读取(不重启、不触发
server 流水线);官网下载页的版本徽章/下载链接/更新日志时间线运行时经
/api/v1/public/release 动态拉取(API 不可达回退构建时静态内容)。为此一次性
扩展后端 changelog 字段(version.go/public.go)与 download.njk 动态渲染。

CHANGELOG.md 重命名为 CHANGELOG-client.md,新增 CHANGELOG-site/server.md;
重写 /release 命令为 /release <part> [version];同步更新 CLAUDE.md 与部署文档。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-17 08:21:28 +08:00

181 lines
5.8 KiB
Markdown
Raw Permalink 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.
# NAS + Gitea 部署文档
## 概述
岩美酒库管理系统使用 **群晖 NAS 上自托管的 GiteaForgejo** 作为代码仓库和 CI/CD 平台。代码推送到 `main` 分支后,NAS 上的 Gitea Runner 自动构建并部署到 EC2 服务器。
---
## 服务地址
| 服务 | 地址 |
|------|------|
| Gitea Web UI | `https://git.51yanmei.com` |
| Gitea SSH | `ssh://git@git.51yanmei.com:2222` |
| Actions 面板 | `https://git.51yanmei.com/wangjia/jiu/actions` |
| 线上应用 | `https://jiu.51yanmei.com` |
| 管理端 Web | `https://jiu.51yanmei.com/app/` |
---
## Gitea Runner 说明
Runner 实际运行在**本机 Mac**(不是 NAS),通过 LaunchAgent 开机自启,连接 NAS 上的 Forgejo。
### 本机文件布局
| 文件 | 说明 |
|------|------|
| `/Users/wangjia/bin/act_runner` | act_runner 二进制(v0.2.11 |
| `/Users/wangjia/bin/act_runner_start.sh` | 启动脚本(含 TCP 中继逻辑) |
| `/Users/wangjia/bin/tcp_relay.py` | Python3 TCP 中继(旧内网方案,现已通过域名直连) |
| `/Users/wangjia/.act_runner` | Runner 注册信息 |
| `/Users/wangjia/.act_runner_config.yaml` | Runner 配置(label: `mac:host`capacity: 1 |
| `~/Library/LaunchAgents/com.jiu.act-runner.plist` | LaunchAgent plist,开机自启 |
| `/tmp/act_runner.log` | 运行日志 |
### Workflow 标签
`.gitea/workflows/deploy-{client,site,server}.yml` 中使用 `runs-on: mac`,对应 runner label `mac:host`
### 检查 Runner 状态
```bash
# 查看日志
tail -f /tmp/act_runner.log
# 确认进程在跑
ps aux | grep act_runner | grep -v grep
# 手动重启(LaunchAgent 会自动重启,一般不需要)
kill $(pgrep -f act_runner_start.sh)
```
### Runner 不工作时的排查步骤
1. **确认 Gitea 可达**`curl -sf https://git.51yanmei.com/api/v1/version`
2. **查看最近日志**`tail -30 /tmp/act_runner.log`
3. **手动测试**`/Users/wangjia/bin/act_runner daemon --config ~/.act_runner_config.yaml`(从终端运行应直接成功)
4. **强制重启**`kill $(pgrep -f act_runner_start.sh)` — LaunchAgent 会在几秒内自动重拉
### 重新注册 Runnertoken 失效时)
```bash
# 1. 停止当前 runner
kill $(pgrep -f act_runner_start.sh)
# 2. 删除旧注册文件
rm ~/.act_runner
# 3. 在 Forgejo 获取新 token
# Settings → Actions → Runners → Create Runner Token
# 4. 注册(从终端运行,不要从 LaunchAgent
/Users/wangjia/bin/act_runner register \
--no-interactive \
--instance https://git.51yanmei.com \
# SSH remote: ssh://git@git.51yanmei.com:2222/wangjia/jiu.git
--token <新token> \
--name mac-runner \
--labels mac:host
# 5. 重启(LaunchAgent 自动接管)
kill $(pgrep -f act_runner_start.sh)
```
---
## Workflows
仓库根目录 `.gitea/workflows/` 下有三个 workflow 文件:
### `deploy-{client,site,server}.yml` — 三条独立部署流程
发版已拆成三条互不影响的流水线,按 tag 前缀触发:
| workflow | 触发 tag | 范围 |
|----------|---------|------|
| `deploy-client.yml` | `client-v*.*.*` | Flutter 全平台 + version.yaml |
| `deploy-site.yml` | `site-v*.*.*` | Eleventy 营销站 |
| `deploy-server.yml` | `server-v*.*.*` | Go 后端 + nginx |
**步骤(各自):** `compile-<part>*.sh` 编译打包 → `test.sh <part>` 门禁 → `release-<part>.sh` 创建 Forgejo Release → `deploy-<part>.sh` SSH 到 EC2 部署 → Telegram 通知。公共函数在 `scripts/ci/lib-forgejo.sh`
### `manual.yml` — 手动部署 / 回滚
**触发条件:** Forgejo UI 手动触发(workflow_dispatch),输入带前缀 tag(如 `client-v1.0.55`),按前缀路由到对应 `deploy-<part>.sh`
**步骤:** 只运行 `deploy.sh`,从 Forgejo Release 下载已有产物直接部署,跳过编译和测试。
### `ci.yml` — PR 测试流程
**触发条件:**`main` 分支的 push 或 PR
**步骤:** 只跑测试(`go test` + `flutter test`),不构建不部署。
---
## Secrets 配置
在 Gitea 仓库的 **Settings → Secrets** 中配置以下密钥:
| Secret 名称 | 用途 |
|-------------|------|
| `EC2_SSH_KEY` | EC2 服务器的 SSH 私钥(PEM 格式,完整内容) |
| `EC2_HOST` | EC2 服务器 IP 或域名 |
| `EC2_USER` | EC2 SSH 用户名(如 `ec2-user``ubuntu` |
| `FORGEJO_TOKEN` | Gitea 个人访问 Token(用于创建 Release、下载 asset |
| `FORGEJO_URL` | Gitea 地址:`https://git.51yanmei.com` |
| `TELEGRAM_TOKEN` | Telegram Bot Token(部署通知) |
| `TELEGRAM_CHAT_ID` | Telegram Chat ID(接收通知的对话) |
---
## 触发部署方式
```bash
# 开发完成,确认测试通过后打 tag
git tag -a v1.1.0 -m "v1.1.0"
git push nas main && git push nas v1.1.0
# → CI 自动:compile → test → release → deploy → Telegram 通知
```
**回滚:** Forgejo UI → Actions → Manual Deploy → 输入旧 tag → Run
---
## EC2 服务器目录结构
```
/opt/jiu/
├── backend/
│ ├── jiu-server # Go 可执行文件
│ └── config/
│ └── version.yaml # 版本信息(由 CI 自动更新)
├── web/ # Flutter Web 构建产物(/app/ 路径)
├── marketing/ # 营销站点静态 HTML
│ ├── assets/
│ ├── index.html
│ ├── docs.html
│ └── download.html
├── images/ # 商品图片上传目录
└── web-old/ # 上一版本 Flutter Web(回滚备用)
```
Systemd 服务名:`jiu`
日志:`journalctl -u jiu -f`
---
## Nginx 路由说明
配置文件:`deploy/nginx-jiu.conf`CI 部署时自动更新)
| 路径 | 服务 |
|------|------|
| `/api/*`, `/health`, `/version` | Go 后端 API |
| `/images/*` | 商品图片静态文件 |
| `/app/` | Flutter 管理端 SPA |
| `/product/<uuid>` | 商品扫码公开页(Flutter Web 路由) |
| `/` | 营销首页 |