99f34a6223
scan.html 从未被实际触发——二维码 URL 格式为 /product/<uuid>, 由 Flutter Web PublicProductScreen 处理,scan.html 是孤立死页。 - 删除 web/scan.html - 移除 nginx-jiu.conf 中 /scan/ location 块 - 更新文档路由表(/scan/<id> → /product/<uuid>) - 标记 todo #4 完成 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
5.5 KiB
5.5 KiB
NAS + Gitea 部署文档
概述
岩美酒库管理系统使用 群晖 NAS 上自托管的 Gitea(Forgejo) 作为代码仓库和 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.yml 和 ci.yml 中使用 runs-on: mac,对应 runner label mac:host。
检查 Runner 状态
# 查看日志
tail -f /tmp/act_runner.log
# 确认进程在跑
ps aux | grep act_runner | grep -v grep
# 手动重启(LaunchAgent 会自动重启,一般不需要)
kill $(pgrep -f act_runner_start.sh)
Runner 不工作时的排查步骤
- 确认 Gitea 可达:
curl -sf https://git.51yanmei.com/api/v1/version - 查看最近日志:
tail -30 /tmp/act_runner.log - 手动测试:
/Users/wangjia/bin/act_runner daemon --config ~/.act_runner_config.yaml(从终端运行应直接成功) - 强制重启:
kill $(pgrep -f act_runner_start.sh)— LaunchAgent 会在几秒内自动重拉
重新注册 Runner(token 失效时)
# 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.yml — 主部署流程
触发条件: push v*.*.* tag
步骤:
compile.sh— 编译 Go 后端(linux/amd64)+ Flutter Web,打包到dist/test.sh—go test+flutter analyzerelease.sh— 解析 CHANGELOG.md,更新 version.yaml,创建 Forgejo Release,上传 3 个 assetdeploy.sh— SSH 到 EC2 部署,完成后发 Telegram 通知
manual.yml — 手动部署 / 回滚
触发条件: Forgejo UI 手动触发(workflow_dispatch),输入目标 tag(如 v1.0.0)
步骤: 只运行 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(接收通知的对话) |
触发部署方式
# 开发完成,确认测试通过后打 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 路由) |
/ |
营销首页 |