4ed906e5fa
CI/CD Pipeline / Check if frontend-only change (push) Has been skipped
CI/CD Pipeline / Dedup Check - skip PR tests when covered by push pipeline (push) Successful in 1s
CI/CD Pipeline / Check push changed paths (pull_request) Has been skipped
CI/CD Pipeline / Dedup Check - skip PR tests when covered by push pipeline (pull_request) Successful in 2s
CI/CD Pipeline / Check if frontend-only change (pull_request) Successful in 4s
CI/CD Pipeline / Frontend Lint (push) Has been skipped
CI/CD Pipeline / PR Build API Image (push) Has been skipped
CI/CD Pipeline / PR Build Web Image (push) Has been skipped
CI/CD Pipeline / Build Staging API Image (pull_request) Has been skipped
CI/CD Pipeline / PR Build Worker Image (push) Has been skipped
CI/CD Pipeline / Build Staging Web Image (pull_request) Has been skipped
CI/CD Pipeline / Build Staging Worker Image (pull_request) Has been skipped
CI/CD Pipeline / Validate - Style (pull_request) Has been skipped
CI/CD Pipeline / Validate - Security (pull_request) Has been skipped
CI/CD Pipeline / Validate - Python (mypy + alembic) (pull_request) Has been skipped
CI/CD Pipeline / Unit Tests (pull_request) Has been skipped
CI/CD Pipeline / Integration Tests (pull_request) Has been skipped
CI/CD Pipeline / Frontend Lint (pull_request) Has been skipped
CI/CD Pipeline / Frontend Unit Tests (pull_request) Has been skipped
CI/CD Pipeline / Check push changed paths (push) Successful in 16s
CI/CD Pipeline / Retag skipped Staging API Image (pull_request) Has been skipped
CI/CD Pipeline / Retag skipped Staging Web Image (pull_request) Has been skipped
CI/CD Pipeline / Retag skipped Staging Worker Image (pull_request) Has been skipped
CI/CD Pipeline / Build Production API Image (pull_request) Has been skipped
CI/CD Pipeline / Build Production Worker Image (pull_request) Has been skipped
CI/CD Pipeline / Build Production Web Image (pull_request) Has been skipped
CI/CD Pipeline / PR Build Web Image (pull_request) Successful in 46s
CI/CD Pipeline / PR Build API Image (pull_request) Successful in 56s
CI/CD Pipeline / Build Staging API Image (push) Successful in 35s
CI/CD Pipeline / Deploy Staging (Watchtower auto-deploy) (pull_request) Has been skipped
CI/CD Pipeline / Deploy Production (pull_request) Has been skipped
CI/CD Pipeline / Production Browser E2E (pull_request) Has been skipped
CI/CD Pipeline / Build Staging Web Image (push) Successful in 20s
CI/CD Pipeline / Staging E2E Tests (pull_request) Has been skipped
CI/CD Pipeline / Staging API Integration Tests (pull_request) Has been skipped
CI/CD Pipeline / ACR Image Cleanup (pull_request) Has been skipped
CI/CD Pipeline / Canary Release to Production (pull_request) Has been skipped
CI/CD Pipeline / PR Build Worker Image (pull_request) Successful in 57s
CI/CD Pipeline / CI Gate (pull_request) Successful in 1s
CI/CD Pipeline / Build Staging Worker Image (push) Successful in 26s
CI/CD Pipeline / Retag skipped Staging API Image (push) Has been skipped
CI/CD Pipeline / Retag skipped Staging Web Image (push) Has been skipped
CI/CD Pipeline / Retag skipped Staging Worker Image (push) Has been skipped
Preview Deploy / Deploy Preview Environment (pull_request) Successful in 1m46s
CI/CD Pipeline / Deploy Staging (Watchtower auto-deploy) (push) Successful in 1m10s
PR Automation / Auto Approve on CI Green (pull_request) Successful in 3m29s
PR Automation / Auto Merge on CI Green + Approved (pull_request) Has been skipped
CI/CD Pipeline / Integration Tests (push) Successful in 4m50s
CI/CD Pipeline / ACR Image Cleanup (push) Successful in 2m2s
CI/CD Pipeline / Validate - Style (push) Has been cancelled
CI/CD Pipeline / Deploy Production (push) Has been cancelled
CI/CD Pipeline / Unit Tests (push) Has been cancelled
CI/CD Pipeline / Build Production API Image (push) Has been cancelled
CI/CD Pipeline / Build Production Web Image (push) Has been cancelled
CI/CD Pipeline / Build Production Worker Image (push) Has been cancelled
CI/CD Pipeline / Production Browser E2E (push) Has been cancelled
CI/CD Pipeline / Canary Release to Production (push) Has been cancelled
CI/CD Pipeline / CI Gate (push) Has been cancelled
CI/CD Pipeline / Validate - Security (push) Has been cancelled
CI/CD Pipeline / Validate - Python (mypy + alembic) (push) Has been cancelled
CI/CD Pipeline / Frontend Unit Tests (push) Has been cancelled
CI/CD Pipeline / Staging E2E Tests (push) Has been cancelled
CI/CD Pipeline / Staging API Integration Tests (push) Has been cancelled
AI Code Review / AI Code Review (pull_request) Has been cancelled
Co-authored-by: xiaoxia <dev@xiaoxiajianji.com> Co-committed-by: xiaoxia <dev@xiaoxiajianji.com>
168 lines
7.2 KiB
Markdown
168 lines
7.2 KiB
Markdown
# 部署说明
|
||
|
||
## 唯一部署入口
|
||
|
||
小虾 SaaS 当前唯一有效 Docker 部署入口是:
|
||
|
||
- `infra/docker/compose.yml`
|
||
- `infra/docker/api.Dockerfile`
|
||
- `infra/docker/worker.Dockerfile`
|
||
- `infra/docker/web.Dockerfile`
|
||
- `infra/docker/deploy-staging.sh`
|
||
|
||
- `infra/docker/infra-production.yml`(production DB/Redis 独立基础设施)
|
||
|
||
仓库根目录的 `Dockerfile` 和 `docker-compose.yml` 已废弃,只作为防误用哨兵保留,不允许用于部署。
|
||
|
||
---
|
||
|
||
## 环境加载规则
|
||
|
||
### 开发环境
|
||
- 默认读取 `.env`
|
||
- 没有 `.env` 时回退到代码默认值
|
||
|
||
### Staging
|
||
- 服务器环境文件:`/var/lib/xiaoxia-saas-staging/.env`
|
||
- `APP_ENV=staging`
|
||
- `WEB_PORT=3001`
|
||
- 由 Gitea Actions 调用 `infra/docker/deploy-staging.sh`
|
||
|
||
### Production
|
||
- 生产环境文件:`/var/lib/xiaoxia-saas-production/.env`
|
||
- `APP_ENV=production`
|
||
- Production DB/Redis 独立于 staging:`xiaoxia-postgres-production:5432`、`xiaoxia-redis-production:6379`
|
||
- 宿主端口:Postgres `5433`、Redis `6380`、API `8001`、Web `3002`
|
||
- 只允许通过 tag/release 触发生产应用部署
|
||
- API/Worker 必须来自专用构建机或 CI 产出的 runtime image tar:`/var/lib/xiaoxia-saas-production/runtime-images-<tag>.tar`
|
||
- Web 必须来自专用构建机或 CI 产出的 prebuilt dist/release artifact,不允许在业务服务器执行前端构建
|
||
- 生产机只能接收产物、解压 release artifact、`docker load` runtime image tar、执行迁移、重启容器和健康检查
|
||
- 禁止在生产机上构建 API/Worker/Web 镜像;当前生产机资源有限且承载业务服务,不是构建机
|
||
- 必须替换所有密钥和 `CHANGE_ME` 项
|
||
|
||
---
|
||
|
||
## 本地/手动部署
|
||
|
||
从仓库根目录执行:
|
||
|
||
```bash
|
||
docker compose -f infra/docker/compose.yml up -d --build
|
||
```
|
||
|
||
Staging 手动部署应复用同一入口:
|
||
|
||
```bash
|
||
cp /var/lib/xiaoxia-saas-staging/.env .env
|
||
WEB_PORT=3001 docker compose -f infra/docker/compose.yml up -d --build
|
||
```
|
||
|
||
服务器自动部署使用:
|
||
|
||
```bash
|
||
infra/docker/deploy-staging.sh
|
||
```
|
||
|
||
部署脚本会在服务启动前执行 Alembic:
|
||
|
||
- 已存在 `alembic_version` 时执行 `alembic upgrade head`
|
||
- 已存在业务表但缺少 `alembic_version` 时执行 `alembic stamp head && alembic upgrade head`
|
||
- 空库时执行 `alembic upgrade head`
|
||
|
||
staging 已在 2026-06-21 验证:`alembic_version = 002`,健康检查通过。
|
||
|
||
---
|
||
|
||
## 外部服务配置
|
||
|
||
认证邮件和 session 存储为配置驱动:
|
||
|
||
- `ENABLE_EMAIL_DELIVERY=false` 时使用 no-op 邮件服务,不对外发送邮件。
|
||
- `ENABLE_EMAIL_DELIVERY=true` 时必须配置 `SMTP_HOST`、`SMTP_PORT`、`SMTP_USER`、`SMTP_PASSWORD`、`SMTP_FROM_EMAIL`、`SMTP_FROM_NAME`、`SMTP_USE_TLS`。
|
||
- `ENABLE_REDIS_SESSIONS=false` 时登录不会写 Redis session,JWT 仍可用于当前认证链路。
|
||
- `ENABLE_REDIS_SESSIONS=true` 时通过 `REDIS_URL` 创建 Redis session store。
|
||
|
||
Staging 当前可以保持 no-op;Production 开启前必须先验证 SMTP/Redis 连接和密钥。
|
||
|
||
---
|
||
|
||
## 生成文件存储与保留
|
||
|
||
- Staging 未配置 OSS 凭证时,生成视频落盘到 `/var/lib/xiaoxia-saas-staging/generated`,并通过 Nginx `/generated-files/` 公开访问。
|
||
- Docker volume host path 由 `GENERATED_FILES_HOST_DIR` 控制,默认仅适用于 staging:`/var/lib/xiaoxia-saas-staging/generated`。
|
||
- Production 优先使用 OSS;若临时启用本地 fallback,必须配置独立持久化目录、Nginx 只读公开路径和磁盘告警。
|
||
- OSS lifecycle rule 必须在生产 bucket 上配置并记录 rule id:临时/失败任务产物建议 7 天删除;订单/购买关联产物由业务保留策略单独保护。
|
||
- 保留策略建议:staging 生成文件保留 7 天或保留最近 20GB;production 按业务套餐/订单状态定义,禁止无上限增长。
|
||
- 清理脚本上线前必须先 dry-run 输出待删列表,再按 workspace/project 维度删除,避免误删仍被 GeneratedVideo 记录引用的文件。
|
||
- 当前脚本:`python scripts/cleanup_generated_files.py --dir /var/lib/xiaoxia-saas-staging/generated --days 7` 仅 dry-run;确认后再加 `--apply`。
|
||
|
||
---
|
||
|
||
## 生产发布清单
|
||
|
||
生产发布前必须按 `docs/PRODUCTION-RELEASE-CHECKLIST.md` 执行:先备份,后 Alembic,最后 smoke;禁止靠临场记忆操作数据库。
|
||
|
||
---
|
||
|
||
## Staging 服务器 Docker 凭证配置
|
||
|
||
Staging 服务器(116.62.226.203)需要配置 ACR 和 Gitea Registry 凭证,否则 docker pull 和 Watchtower 自动更新会失败。
|
||
|
||
### 凭证文件位置
|
||
- Docker 配置文件:`/root/.docker/config.json`
|
||
- 包含两个 registry 的认证信息:
|
||
- `xiaoxia-registry.cn-hangzhou.cr.aliyuncs.com`(阿里云 ACR)
|
||
- `git.xiaoxiajianji.com`(Gitea 容器镜像仓库)
|
||
|
||
### 服务器迁移后恢复步骤
|
||
```bash
|
||
# 1. 登录 ACR
|
||
docker login xiaoxia-registry.cn-hangzhou.cr.aliyuncs.com -u <ACR_USERNAME>
|
||
|
||
# 2. 登录 Gitea Registry
|
||
docker login git.xiaoxiajianji.com -u xiaoxia -p <GITEA_REGISTRY_TOKEN>
|
||
|
||
# 3. 重启 Watchtower(确保挂载最新 config.json)
|
||
docker restart watchtower
|
||
```
|
||
|
||
### Watchtower 配置
|
||
- 容器名:`watchtower`
|
||
- 检查间隔:300 秒(5 分钟)
|
||
- 监控容器:`xiaoxia-api-staging`、`xiaoxia-worker-staging`、`xiaoxia-web-staging`
|
||
- 必须挂载 `-v /root/.docker/config.json:/config.json` 才能拉取私有镜像
|
||
- 必须挂载 `-v /var/run/docker.sock:/var/run/docker.sock` 才能管理容器
|
||
- 容器使用 `:dev` 稳定 tag,Watchtower 通过检测 `:dev` tag 的 digest 变化来发现更新
|
||
|
||
### 镜像 Tag 策略
|
||
- CI 每次构建推送三种 tag:`${GITHUB_SHA}`(精确版本)、`${GITHUB_REF_NAME}`(分支名)、`:dev`(滚动 tag,仅 develop 分支)
|
||
- Staging 容器统一使用 `:dev` tag 启动,确保 Watchtower 能自动发现新版本
|
||
- Migration(alembic)使用 commit SHA tag 执行,不依赖 Watchtower
|
||
|
||
---
|
||
|
||
## Gitea Actions 约定
|
||
|
||
- `develop` 分支触发 staging 部署。
|
||
- tag `v*` 才允许触发 production 部署。
|
||
- Actions 先同步代码到 `/var/lib/xiaoxia-saas-staging/repo`。
|
||
- Actions 再复制 `/var/lib/xiaoxia-saas-staging/.env` 到部署工作目录。
|
||
- Actions 最终调用 `infra/docker/deploy-staging.sh`。
|
||
- Production tag deploy 会传入 `RELEASE_VERSION=${GITHUB_REF_NAME}`。
|
||
- Production deploy 必须先上传 runtime image tar;缺少 tar 时 `infra/docker/deploy-production.sh` 必须失败,防止代码已更新但 API/Worker 仍运行旧镜像。
|
||
- API/Worker runtime image tar 构建命令:`scripts/build_release_images.sh <tag>`。
|
||
- runtime image tar 生产部署入口:`scripts/deploy_release_images_production.sh <tag> <tar>` 或由 tag deploy 调用 `infra/docker/deploy-production.sh` 加载 `/var/lib/xiaoxia-saas-production/runtime-images-<tag>.tar`。
|
||
|
||
---
|
||
|
||
## 注意事项
|
||
|
||
- 不要使用根目录 `Dockerfile`。
|
||
- 不要使用根目录 `docker-compose.yml`。
|
||
- `.env.production` 不要提交真实密钥。
|
||
- OSS、数据库、Redis、JWT 密钥必须通过服务器环境文件注入。
|
||
- 生产环境必须设置 `DEBUG=false`。
|
||
- staging / production 不允许开启 `AUTO_CREATE_SCHEMA` 绕过 Alembic。
|
||
- 生产机禁止构建 API/Worker runtime 镜像;如发现需要构建,先补构建机/CI 产物流程,不得临时开启生产构建。
|
||
- `scripts/build_release_images.sh` 会检测生产容器;如果当前机器运行生产服务,默认拒绝构建 runtime 镜像。
|