Files
ai-ticket-platform/docs/operations/production-runbook.md
2026-09-18 15:26:19 +08:00

11 KiB
Raw Permalink Blame History

生产部署与恢复手册

本文适用于单机 Docker Compose 私有化部署,覆盖首次部署、升级、监控、备份、恢复和 故障处理。多节点、高可用数据库和企业 Kubernetes 部署需要在此基线之上另行设计。

1. 部署拓扑与前置条件

生产 Compose 包含:

  • PostgreSQL 16 + pgvector
  • Redis 7
  • MinIO
  • ClamAV
  • Django + Gunicorn
  • Celery Worker、Celery Beat
  • Nginx 静态前端与 API 反向代理
  • 可选 Prometheus、Alertmanager

最低前置条件:

  • 64 位 Linux
  • Docker Engine 与 Compose 插件
  • 可持续运行的本地或挂载数据盘
  • 企业 DNS 和 TLS 证书
  • NTP 时间同步
  • 独立备份目录和异地加密存储

试运行建议至少 4 核 CPU、8 GB 内存和 100 GB 可用磁盘;正式规格必须根据附件量、 模型并发、知识向量和保留周期压测确定。ClamAV 病毒库初始化和 PostgreSQL/MinIO 数据量 会显著影响内存与磁盘需求。

2. 目录、账号和权限

建议使用专用系统账号部署,例如 ai-ticket:

/opt/ai-ticket-platform/       应用代码和 .env
/var/lib/ai-ticket-backups/    本机备份
/etc/ai-ticket/                监控令牌和告警地址

要求:

  • .env、监控令牌和告警 Webhook 仅部署账号可读。
  • 备份账号只拥有 Docker 和备份目录所需权限。
  • 不把 Docker Socket、PostgreSQL、Redis、MinIO 或 ClamAV 端口暴露到公网。
  • infra/secrets/*.example 只是结构示例,不能作为生产凭据。

3. 生产配置

复制模板:

cp .env.example .env
chmod 600 .env

必须修改:

DJANGO_DEBUG=false
DJANGO_SECRET_KEY=<高强度随机值>
DJANGO_ALLOWED_HOSTS=tickets.example.com
CORS_ALLOWED_ORIGINS=https://tickets.example.com
CSRF_TRUSTED_ORIGINS=https://tickets.example.com
FRONTEND_APP_URL=https://tickets.example.com
OIDC_CALLBACK_BASE_URL=https://tickets.example.com

DJANGO_SUPERUSER_PASSWORD=<首次登录后仍需立即轮换>
POSTGRES_PASSWORD=<数据库密码>
MINIO_ROOT_USER=<MinIO 管理账号>
MINIO_ROOT_PASSWORD=<MinIO 管理密码>
MINIO_ACCESS_KEY=<应用访问账号>
MINIO_SECRET_KEY=<应用访问密钥>

AI_CREDENTIAL_ENCRYPTION_KEY=<稳定 Fernet 密钥>
INTERNAL_MCP_TOKEN=<独立随机令牌>
METRICS_TOKEN=<独立随机令牌>

TICKET_AUTOMATION_ENABLED=false
TICKET_AUTOMATION_MAX_RETRIES=2
TICKET_AUTO_CLOSE_HOURS=24
SUPPORT_REFERENCE_MIN_SCORE=0.35

Fernet 密钥生成:

python -c "from cryptography.fernet import Fernet; print(Fernet.generate_key().decode())"

密钥一旦用于加密模型、MCP、渠道或 OIDC 凭据,必须进入企业密钥备份流程。直接替换会导致 历史密文不可解密。

生产建议:

  • KNOWLEDGE_EMBEDDING_ALLOW_HASH_FALLBACK=false
  • TICKET_AUTO_RESOLVE_ENABLED=false,完成真实案例验收后再按策略开启
  • TICKET_AUTOMATION_ENABLED=false,完成受理 Agent、支持分析 Agent、模型部署、 Celery、MinIO 和至少一种回复送达方式的就绪检查后再开启
  • TICKET_AUTO_CLOSE_HOURS=24 是无异议窗口;变更前应完成客户通知与合规评审
  • Celery Beat 必须保持单实例运行,否则虽有数据库幂等保护,仍会制造无意义的重复调度
  • 使用正式 Embedding 部署并保持向量维度与数据库字段一致
  • 根据数据保留政策设置 Agent 运行和临时受理保留周期
  • 默认管理员仅用于初始化,随后创建实名管理员并停用或轮换默认账号

4. TLS 与网络边界

仓库 Compose 暴露 ${HTTP_PORT:-8080} 的 HTTP 服务。生产环境应在其前方部署企业负载 均衡器或 TLS 反向代理:

  • 外部只开放 443。
  • HTTP 强制跳转 HTTPS。
  • 保留 Host、X-Forwarded-Proto 和真实客户端 IP。
  • 限制上传体积不低于平台总材料上限 100 MB。
  • /internal-mcp、MinIO 控制台和监控端点只允许可信网络访问。
  • 对模型、MCP、OIDC 和渠道出站目标使用网络白名单,应用层 URL 校验不能替代防火墙。

OIDC 回调地址固定为:

https://<域名>/api/identity/auth/oidc/<provider-slug>/callback

5. 首次部署

先校验变量展开:

docker compose -f infra/docker-compose.prod.yml --env-file .env config

构建并启动:

docker compose -f infra/docker-compose.prod.yml --env-file .env up -d --build
docker compose -f infra/docker-compose.prod.yml --env-file .env ps

后端入口会等待 PostgreSQL、执行迁移并初始化治理数据。首次部署仍应检查日志:

docker compose -f infra/docker-compose.prod.yml --env-file .env logs backend --tail 200
docker compose -f infra/docker-compose.prod.yml --env-file .env logs worker --tail 100
docker compose -f infra/docker-compose.prod.yml --env-file .env logs beat --tail 100

探针:

curl -fsS http://127.0.0.1:8080/api/system/health/live
curl -fsS http://127.0.0.1:8080/api/system/health/ready

live 只表示进程可响应;ready 同时检查数据库和缓存。部署完成后验证:

  1. HTTPS、登录和权限菜单。
  2. 创建、查询和状态流转一张测试工单。
  3. 上传安全测试附件并下载。
  4. 启动一次 Agent 运行并查看事件。
  5. 如已配置渠道,执行入站、出站和回执。
  6. 检查后台任务、指标和告警。

6. 监控与告警

创建仅运维账号可读的文件:

install -m 600 /dev/null /etc/ai-ticket/metrics-token
install -m 600 /dev/null /etc/ai-ticket/alert-webhook-url

写入与 .env 中 METRICS_TOKEN 一致的指标令牌,以及真实告警 Webhook。设置路径并启动:

export METRICS_TOKEN_FILE=/etc/ai-ticket/metrics-token
export ALERT_WEBHOOK_URL_FILE=/etc/ai-ticket/alert-webhook-url
docker compose -f infra/docker-compose.prod.yml --env-file .env \
  --profile monitoring up -d

Prometheus 与 Alertmanager 默认只绑定宿主机回环地址。指标接口接受 X-Metrics-Token 或 Bearer Token。当前告警覆盖:

  • 后端无法抓取
  • 渠道失败或积压
  • Agent/Tool 近期失败
  • 任务中心积压

上线前必须触发一条测试告警,确认接收人、升级路径、静默策略和恢复通知。

7. 备份、校验和保留

Linux:

sh infra/scripts/backup.sh
sh infra/scripts/verify-backup.sh backups/<timestamp>
BACKUP_RETENTION_DAYS=30 sh infra/scripts/prune-backups.sh

Windows PowerShell:

& infra/scripts/backup.ps1
& infra/scripts/verify-backup.ps1 -BackupDirectory backups/<timestamp>

备份包含:

  • PostgreSQL 自定义格式转储
  • 可枚举数据库结构清单
  • MinIO 数据归档
  • SHA-256 校验文件
  • 备份元数据

默认流程会暂停运行中的 backend、worker 和 beat,并在对象卷归档期间停止 MinIO, 形成数据库与对象存储的一致静默窗口。只有确认没有常驻业务写入的隔离演练才允许使用 BACKUP_SKIP_APPLICATION_SERVICES=true 或 -SkipApplicationServices。

infra/backup-cron.example 是宿主机 cron 模板。安装前替换绝对路径和专用账号。校验成功的 备份必须复制到独立、加密、不可被应用主机直接删除且具有保留策略的异地存储。

备份成功不代表可恢复;至少按季度执行恢复演练,并在重大版本发布前再次执行。

8. 升级

升级前:

  1. 确认当前 Git 版本和镜像标签可追溯。
  2. 阅读迁移和配置变更。
  3. 执行完整质量门和生产 Compose 校验。
  4. 创建并验证一致性备份。
  5. 记录维护窗口和回滚负责人。

构建新版本:

docker compose -f infra/docker-compose.prod.yml --env-file .env build
docker compose -f infra/docker-compose.prod.yml --env-file .env up -d

观察:

docker compose -f infra/docker-compose.prod.yml --env-file .env ps
docker compose -f infra/docker-compose.prod.yml --env-file .env logs backend worker --tail 200
curl -fsS http://127.0.0.1:8080/api/system/health/ready

然后执行首次部署中的业务冒烟。迁移必须向后兼容时,才允许应用容器滚动替换;破坏性迁移 需要单独维护窗口和数据转换方案。

9. 回滚

应用回滚:

  1. 停止写入或进入维护窗口。
  2. 切回已验证的代码版本和镜像标签。
  3. 使用相同 .env 启动旧版本。
  4. 检查就绪探针和业务冒烟。

数据库迁移不能盲目反向执行。若新版本已写入旧版本不理解的数据,使用升级前的一致性备份 恢复数据库与 MinIO,而不是只恢复其中一侧。

10. 恢复

恢复会替换当前数据库和对象存储,只能在确认的维护窗口执行。

Linux:

RESTORE_CONFIRM=restore-ai-ticket-platform \
  sh infra/scripts/restore.sh backups/<timestamp>

Windows PowerShell:

& infra/scripts/restore.ps1 `
  -BackupDirectory backups/<timestamp> `
  -Confirm restore-ai-ticket-platform

脚本会先验证备份,在覆盖对象卷前停止 MinIO,并在 MinIO 恢复健康后再启动应用服务。 恢复后依次检查:

  1. 就绪探针和登录。
  2. 工单数量、抽样状态和解决结果。
  3. 附件记录与 MinIO 对象。
  4. Agent、任务中心和审计记录。
  5. 渠道入站、出站和回执。

隔离自动演练:

& infra/scripts/drill-restore.ps1

演练创建唯一 Compose 项目和独立数据卷,写入工单、附件及 MinIO 标记,执行备份、删除、 恢复和一致性检查,最后清理临时资源。最近一次证据见 隔离恢复演练记录。

11. 故障排查

就绪探针失败

docker compose -f infra/docker-compose.prod.yml --env-file .env ps
docker compose -f infra/docker-compose.prod.yml --env-file .env logs backend postgres redis --tail 200

重点检查数据库连接、Redis 地址、迁移状态和磁盘空间。

Celery 任务积压

检查 worker、Redis 和模型服务连通性。不要通过重复点击绕过幂等控制;先确认任务是否已经 创建业务终态。

材料一直扫描失败

检查 ClamAV 健康和病毒库日志。不得为恢复业务而在生产关闭恶意文件扫描。

模型、MCP、渠道或 OIDC 凭据无法解密

确认 Django 与 Celery 使用同一 Fernet 主密钥。不要覆盖主密钥;从企业密钥备份恢复原值。

磁盘快速增长

分别检查 PostgreSQL、MinIO、ClamAV、Prometheus 和备份目录。先确认保留策略和备份可恢复, 不要直接删除 Docker 数据卷。

12. 上线安全检查表

  • DJANGO_DEBUG=false,域名和可信来源仅包含生产地址。
  • 默认管理员密码已替换,管理员使用实名账号。
  • .env、Fernet、MCP、指标和告警凭据已纳入密钥管理。
  • 外部只开放 HTTPS,内部端口受防火墙限制。
  • 模型、MCP、OIDC 和渠道出口有网络白名单。
  • 自动解决保持关闭,或已经通过真实案例和审批策略验收。
  • 监控、真实告警接收方和升级路径已验证。
  • 定时备份已安装,校验后复制到异地加密存储。
  • 已完成隔离恢复演练并记录 RPO/RTO。
  • 统一蓝图报告明确区分已通过和待真实环境验收门槛。