ci(deploy): deploy images over ssh from gitea actions

This commit is contained in:
2026-07-07 15:02:02 +08:00
parent 6867b165a1
commit 75bc817a59
8 changed files with 290 additions and 62 deletions
+13 -29
View File
@@ -1,12 +1,14 @@
# 自动构建与自动重启流程
# 自动构建与自动重启流程(旧 Git Hook 方案)
本文档说明当前项目通过 Git remote + `post-receive` hook 实现自动部署、自动重启的流程。当前服务器端运行方式已经容器化,核心文件为 [.githooks/post-receive](../.githooks/post-receive)、[Dockerfile](../Dockerfile) 和 [docker-compose.yml](../docker-compose.yml)。
本文档记录旧的 Git remote + `post-receive` hook 部署流程,仅作为回滚参考。当前推荐方案已迁移为 Gitea Actions 构建镜像并通过 SSH 部署,见 [Gitea Actions SSH 部署流程](./gitea-actions-ssh-deploy.md)。
旧方案核心文件为 [.githooks/post-receive](../.githooks/post-receive)、[Dockerfile](../Dockerfile) 和 [docker-compose.yml](../docker-compose.yml)。
服务器默认仍会本地构建 Docker 镜像;如果服务器工作树中存在 `.deploy.env` 且配置 `COZSWEET_DEPLOY_IMAGE_SOURCE=pull`,则会改为从镜像仓库拉取由 Gitea Actions 构建好的镜像。
## 部署入口
## 部署入口
当前涉及两个服务器 remote
旧方案涉及两个服务器 remote
| 环境 | Git remote | 推送分支 | 宿主机端口 | 容器端口 | 部署脚本 |
| --- | --- | --- | --- | --- | --- |
@@ -20,48 +22,30 @@ test root@43.106.13.130:/root/cozsweet-repos/test
production root@43.106.13.130:/root/cozsweet-repos/main
```
常用发布入口:
```bash
# 发布测试环境
./scripts/release/pre_release_web.sh
# 发布生产环境
./scripts/release/release_web.sh
```
也可以只执行推送脚本:
```bash
# 推送 test remote 的 test 分支
./scripts/deploy/deploy_web_test.sh
# 推送 production remote 的 main 分支
./scripts/deploy/deploy_web.sh
```
当前日常发布入口已经改为推送 Gitea 分支并触发 Actions,详见 [Gitea Actions SSH 部署流程](./gitea-actions-ssh-deploy.md)。`scripts/deploy/*` 已改为推送 `gitea` remote,不再推送服务器 remote。旧方案如果需要手动触发,需要直接操作对应服务器仓库。
## 本地发布流程
测试环境发布流程:
测试环境发布流程(脚本迁移前)
1. 进入 test worktree`cozsweet-frontend-nextjs.worktrees/cozsweet-nextjs-test`
2. 确认当前分支。
3. 执行 `git rebase dev`,把 `dev` 的最新代码变基到 `test` 分支。
4. 复制测试环境图标到 `public/`
5. 复制 `env-example/.env.local.example``.env.local`
6. 执行 `scripts/deploy/deploy_web_test.sh`
7. `deploy_web_test.sh` 推送 `test` remote 的 `test` 分支。
6. 执行旧版 `scripts/deploy/deploy_web_test.sh`
7. 旧版 `deploy_web_test.sh` 推送 `test` remote 的 `test` 分支。
8. 推送成功后尝试清除 Cloudflare CDN 缓存。
生产环境发布流程:
生产环境发布流程(脚本迁移前)
1. 进入 main worktree`cozsweet-frontend-nextjs.worktrees/cozsweet-nextjs-main`
2. 确认当前分支。
3. 执行 `git rebase dev`,把 `dev` 的最新代码变基到 `main` 分支。
4. 复制生产环境图标到 `public/`
5. 复制 `env-example/.env.production.example``.env.production`
6. 执行 `scripts/deploy/deploy_web.sh`
7. `deploy_web.sh` 强制推送 `production` remote 的 `main` 分支。
6. 执行旧版 `scripts/deploy/deploy_web.sh`
7. 旧版 `deploy_web.sh` 强制推送 `production` remote 的 `main` 分支。
8. 推送成功后尝试清除 Cloudflare CDN 缓存。
## 服务器端 post-receive 流程
+6 -23
View File
@@ -1,6 +1,6 @@
# Docker 镜像持续构建与发布
本文档说明 Gitea Actions 中 Docker 镜像构建发布 workflow 的使用方式。对应脚本为 [.gitea/workflows/docker-image.yml](../.gitea/workflows/docker-image.yml)。
本文档说明 Gitea Actions 中 Docker 镜像构建发布与 SSH 部署 workflow 的使用方式。对应脚本为 [.gitea/workflows/docker-image.yml](../.gitea/workflows/docker-image.yml)。
## 职责划分
@@ -9,7 +9,7 @@
| Workflow | 触发时机 | 职责 |
| --- | --- | --- |
| `.gitea/workflows/ci.yml` | `dev``main``test` push / PR | 安装依赖、Lint、单元测试、Next.js 构建 |
| `.gitea/workflows/docker-image.yml` | `main``test` push / 手动触发 | 构建 Docker 镜像推送到镜像仓库 |
| `.gitea/workflows/docker-image.yml` | `main``test` push / 手动触发 | 构建 Docker 镜像推送到镜像仓库,并通过 SSH 部署 |
这样可以避免所有开发分支都发布镜像,也能让代码检查失败时不污染镜像仓库。
@@ -90,36 +90,19 @@ docker image ls | grep cozsweet-web
## 部署服务器拉取镜像
部署服务器需要先登录镜像仓库:
当前推荐由 Gitea Actions 通过 SSH 登录部署服务器并执行部署脚本,不再依赖服务器 Git remote 的 `post-receive` hook。完整说明见 [Gitea Actions SSH 部署流程](./gitea-actions-ssh-deploy.md)。
如果需要在服务器上手动验证镜像拉取,可先登录镜像仓库:
```bash
docker login REGISTRY_HOST
```
然后在部署服务器工作树中创建 `.deploy.env`
```bash
cp env-example/.deploy.env.example .deploy.env
```
配置示例:
```env
COZSWEET_DEPLOY_IMAGE_SOURCE=pull
COZSWEET_REGISTRY_IMAGE=gitea.banlv-ai.com/admin/cozsweet-web
```
`post-receive` 会根据当前分支和 commit 自动拉取:
Actions 部署时会根据当前分支和 commit 自动拉取
```bash
gitea.banlv-ai.com/admin/cozsweet-web:test-<short_sha>
gitea.banlv-ai.com/admin/cozsweet-web:prod-<short_sha>
```
如果需要改用 latest tag,可以在服务器 `.deploy.env` 中显式设置:
```env
COZSWEET_REMOTE_IMAGE_TAG=prod-latest
```
推荐优先使用默认的 `<env>-<short_sha>` 精确 tag,这样发布和回滚都更可控。
+110
View File
@@ -0,0 +1,110 @@
# Gitea Actions SSH 部署流程
当前推荐部署链路:
```text
push test/main
→ Gitea Actions 构建并推送 Docker 镜像
→ Actions 通过 SSH 登录目标服务器
→ 目标服务器 docker pull 指定镜像 tag
→ docker compose up -d --no-build
```
服务器不再依赖 Git remote 的 `post-receive` hook 拉取或构建镜像。
## 分支与环境
| 分支 | 环境 | 镜像 tag | 宿主机端口 | 默认服务器目录 | 容器名 |
| --- | --- | --- | --- | --- | --- |
| `test` | 测试环境 | `test-<short_sha>` | `9135` | `/opt/cozsweet-web-test` | `cozsweet-web-test` |
| `main` | 生产环境 | `prod-<short_sha>` | `9185` | `/opt/cozsweet-web-prod` | `cozsweet-web-prod` |
## Gitea Secrets
已有镜像构建 Secrets
| Secret | 说明 |
| --- | --- |
| `REGISTRY_HOST` | Docker registry host,例如 `gitea.banlv-ai.com` |
| `REGISTRY_IMAGE` | 镜像仓库,例如 `gitea.banlv-ai.com/admin/cozsweet-web` |
| `REGISTRY_USERNAME` | registry 用户名 |
| `REGISTRY_PASSWORD` | registry 密码或 token |
| `TEST_ENV_FILE` | 测试环境 `.env.local` 内容 |
| `PRODUCTION_ENV_FILE` | 生产环境 `.env.production` 内容 |
新增 SSH 部署 Secrets
| Secret | 说明 |
| --- | --- |
| `TEST_SSH_HOST` / `PROD_SSH_HOST` | 测试 / 生产服务器地址 |
| `TEST_SSH_USER` / `PROD_SSH_USER` | SSH 用户,例如 `root` |
| `TEST_SSH_PRIVATE_KEY` / `PROD_SSH_PRIVATE_KEY` | 私钥内容 |
| `TEST_SSH_PORT` / `PROD_SSH_PORT` | 可选,默认 `22` |
| `TEST_SSH_KNOWN_HOSTS` / `PROD_SSH_KNOWN_HOSTS` | 可选,推荐配置 `ssh-keyscan` 输出 |
| `TEST_DEPLOY_DIR` / `PROD_DEPLOY_DIR` | 可选,覆盖默认服务器目录 |
| `CF_ZONE_ID` / `CF_API_TOKEN` | 可选,部署成功后清理 Cloudflare 缓存 |
## 服务器要求
目标服务器需要:
1. 安装 Docker,并支持 `docker compose``docker-compose`
2. SSH 用户可执行 Docker 命令。
3. 能访问 Gitea registry。
4. 部署目录允许 SSH 用户写入。
workflow 会自动同步以下文件到服务器部署目录:
```text
docker-compose.yml
deploy-docker-image.sh
.env.local 或 .env.production
```
## 本地发布入口
本地发布脚本现在只负责推送 Gitea 分支,触发 Actions
```bash
# 测试环境
./scripts/release/pre_release_web.sh
# 生产环境
./scripts/release/release_web.sh
```
也可以直接推送:
```bash
git push gitea test
git push --force gitea main
```
## 验证
测试环境:
```bash
ssh <user>@<test-host>
cd /opt/cozsweet-web-test
docker compose ps
curl -I http://127.0.0.1:9135/
```
生产环境:
```bash
ssh <user>@<prod-host>
cd /opt/cozsweet-web-prod
docker compose ps
curl -I http://127.0.0.1:9185/
```
## 旧 hook 处理
服务器上的 Git remote `post-receive` hook 属于旧部署链路。迁移完成并验证 Actions SSH 部署成功后,可以在服务器上禁用旧 hook,避免误触发:
```bash
mv /root/cozsweet-repos/test/.git/hooks/post-receive /root/cozsweet-repos/test/.git/hooks/post-receive.disabled
mv /root/cozsweet-repos/main/.git/hooks/post-receive /root/cozsweet-repos/main/.git/hooks/post-receive.disabled
```