---
name: deploy-ops
description: >
  当用户要求部署到生产/UAT环境、更新代码、回滚版本、验证部署状态，或对生产/UAT
  服务器做"配置类轻量运维"（改环境变量、加凭据、配置证书、改 SSH/服务器配置）时使用。
  覆盖首次部署、日常更新、回滚、部署后验证、env 修改的完整流程。
  触发短语：部署、deploy、上线、发布到生产、更新UAT、回滚、rollback、
  改环境变量、加凭据、配置证书、改 .env、SSH 改服务器配置。
  不触发：本地开发启动（用 setup-project 或 dev.sh）。
---

# 部署运维技能

## 前置条件

- SSH 访问目标服务器的权限
- 目标分支已通过 PR 合并到 develop（test）/ staging（UAT）/ production（生产）
- 服务器环境参考 `docs/ops/01-server-infrastructure.md`

## 环境差异（三个部署目标，对应四层环境的 L2/L3/L4）

| 项目 | Test (L2) | UAT (L3) | 生产 (L4) |
|------|-----------|----------|-----------|
| 分支 | develop | staging | production |
| 域名 | ffworkspace.test.faradayfuturecn.com | ffworkspace.test.faradayfuture.com | 生产域名 |
| env 配置 | `setup-env.sh test` | `setup-env.sh uat` | `setup-env.sh production` |
| CI 触发 | push 到 develop 自动部署 | push 到 staging 自动部署 | push 到 production 自动部署 |
| 部署后跑什么 | 健康检查 + smoke 200（不跑 E2E） | 全量 L1 + 全量 L2 E2E + L1c (UAT 验收库) | smoke + 灰度监控 + L1c read-only + 持续监控 |
| 数据策略 | 可脏，定期 reset | 接近生产（脱敏快照） | 真实数据 |

**关键认知**：L4 生产部署必须跑"环境层"检查（env / 连通性 / smoke / 灰度），不跑业务回归（L3 已兜底）。

## 流程

### 场景 1：首次部署（新服务器）

1. SSH 到服务器
2. `cd /srv/apps && sudo git clone <repo-url> ffoa && cd ffoa`
3. `sudo bash scripts/deploy/setup-production.sh`（安装 Docker/Node/PM2/Nginx，仅首次）
4. `bash scripts/env/setup-env.sh production && vim .env`（配置环境变量）
5. `bash scripts/deploy/deploy.sh deploy`
6. 验证（见下方）

### 场景 2：日常更新

1. SSH 到服务器，cd 到项目目录
2. `git pull origin production`（或 `staging`）
3. `bash scripts/deploy/deploy.sh deploy`
4. 验证

### 场景 3：回滚

1. `git log --oneline -5`（找到要回滚的提交）
2. `git checkout <commit-hash>`
3. `bash scripts/deploy/deploy.sh deploy`
4. 验证

### 部署后验证

```bash
pm2 status                    # 应用进程状态
bash scripts/deploy/deploy.sh health  # 服务健康检查
curl http://localhost:<backend_port>/api/v1/health  # API 健康
curl -I http://localhost:<frontend_port>  # 前端可访问
```

### L4 生产部署的三阶段检查清单

**部署前（必须在合并到 production 前完成）**

- [ ] 环境变量必填项校验：`DATABASE_URL`、外部 API key、第三方服务地址等
- [ ] 连通性检查：DB / Redis / MQ / 第三方 API 可达
- [ ] Migration 风险审查：耗时预估、是否锁表、是否能回滚
- [ ] 数据库备份 + 回滚预案就位

**部署后（关键，不可省）**

- [ ] Smoke test：健康检查 200 / 登录能进 / 首页 200 / 关键 API 200
- [ ] 灰度阶段关键指标监控：错误率 / p95 / QPS / 慢 SQL
- [ ] AI 持续监控：日志 / 告警 / 关键指标
- [ ] L1c 数据质量持续监控（生产 read-only）

**持续（部署完成后长期跑）**

- [ ] 异常告警推 Discord
- [ ] 数据库定期备份
- [ ] 出问题触发回滚到上一个 production tag（人工确认）

## deploy.sh 命令参考

| 命令 | 用途 |
|------|------|
| `deploy` | 完整部署（构建+迁移+重启） |
| `up` / `down` / `restart` | Docker 服务管理 |
| `status` | 查看服务状态 |
| `logs` / `app:logs` | Docker 日志 / 应用日志 |
| `db:migrate` | 运行数据库迁移 |
| `db:backup` / `db:restore <file>` | 备份/恢复 |
| `health` | 健康检查 |

## 新增 env var 操作规范（防漏漏配）

**FFOA 共 5 个部署环境**（FFAI Test / FFAI UAT / FFAI PROD / AIxC UAT / AIxC PROD）。
两套产品共用同一份 Gitea 代码，**任何新 env var 默认 5 处全配**——漏一个就在那套环境上跑空值或 fallback。

### 接到"加 env var"请求的标准流程

```bash
# Step 0: 仓库模板
edit .env.example  # 加 var + 注释（用途 + 缺失症状）

# Step 1: 一键批量（推荐）
bash scripts/ops/sync-env-var.sh NEW_VAR=value
# 自动按 5 环境清单 SSH 备份 + 追加 + diff，可 --dry-run 预演

# 或手工（5 处都要跑，参考 .learnings/2026-05-16-five-envs-not-two.md 完整命令）
ssh ubuntu@170.106.161.71      'cd /srv/apps/ffworkspace-test && cp .env.test .env.test.bak.$(date +%Y%m%d-%H%M) && echo "NEW_VAR=val" >> .env.test'
ssh ubuntu@43.153.69.73        'cd /srv/apps/ffworkspace-test && cp .env.uat  .env.uat.bak.$(date +%Y%m%d-%H%M)  && echo "NEW_VAR=val" >> .env.uat'
ssh srvadmin@43.130.6.44       'cd /srv/apps/ffworkspace      && cp .env.pro  .env.pro.bak.$(date +%Y%m%d-%H%M)  && echo "NEW_VAR=val" >> .env.pro'
ssh itadminaixc@52.234.29.56   'cd /srv/apps/aixcworkspace    && cp .env.uat  .env.uat.bak.$(date +%Y%m%d-%H%M)  && echo "NEW_VAR=val" >> .env.uat'
ssh itadminaixc@23.101.202.65  'cd /srv/apps/aixcworkspace    && cp .env.pro  .env.pro.bak.$(date +%Y%m%d-%H%M)  && echo "NEW_VAR=val" >> .env.pro'
```

### 元规则

接到 "为所有环境加 X" / "全部环境查 Y" 请求时，**先 `grep "^### " docs/ops/01-server-infrastructure.md` 数环境数**，不要凭记忆只想 FFAI UAT + PROD 两台（5 台不是 2 台）。

### 重启 / rebuild 时机

- **后端 env**（DATABASE_URL / API key 等）：改完 `pm2 restart <name>` 立即生效
- **前端 `NEXT_PUBLIC_*` env**：**构建期烧死**，光改 env 不重 build 无效。改完必须：
  ```bash
  ssh <env> 'cd /srv/apps/<root>/frontend && npm run build && pm2 reload <frontend-name>'
  ```
- 仍按 FFOA 流程：**改 env 不要立刻 pm2 操作**，让用户决定时间窗口

## 关键约束

- 生产部署前必须先在 UAT 验证
- 部署前自动备份数据库（deploy.sh 内置）
- 回滚只回退代码，数据库迁移不自动回退（需要时用 db-backup skill）
- **完工 ≠ 命令成功 ≠ 文件存在 ≠ grep 命中**（[5 条规则·规则 4](../../../docs/standards/12-five-meta-rules.md)）
  - 任何"装好了 / 配好了 / 改好了"必须实测对应业务 API 响应正确才算完工
  - 多环境批量任务（4 套环境 × N 套产品）必须用"环境 × 状态"显式表格记录每个环境的实测结果，不靠记忆
  - 实测覆盖：`/api/v1/health` 200 + 一个登录 200 + 一个业务 API 200，缺一不算完

## References

- [`docs/standards/12-five-meta-rules.md`](../../../docs/standards/12-five-meta-rules.md) —— 5 条元根因规则。规则 3（环境一致）和规则 4（实测完工）直接约束 deploy-ops 的工作方式。
- [`docs/standards/11-troubleshooting-methodology.md`](../../../docs/standards/11-troubleshooting-methodology.md) —— 部署事故复盘按 6 段模板走。
