Files
NianAIGC/docs/DEPLOYMENT.md

12 KiB
Raw Blame History

智念AIGC平台部署说明

阿里云 ACK + RDS PostgreSQL生产

生产环境设置 ZHINIAN_DATA_BACKEND=postgres,并通过 Kubernetes Secret 注入 DATABASE_URL。优先使用 RDS 内网连接地址ACK 节点/Pod 与 RDS 必须位于同一 或网络可达的 VPC并在 RDS 白名单或安全组中仅放行实际工作负载网段。

启用 RDS SSL 后,下载实例对应的 CA创建 zhinian-rds-ca Secret并将其挂载到 /etc/zhinian/rds/ca.pem;同时设置 DATABASE_SSL_MODE=verify-fullDATABASE_CA_CERT_PATH=/etc/zhinian/rds/ca.pem。不要使用关闭证书校验的配置。

kubectl -n zhinian create secret generic zhinian-rds-ca \
  --from-file=ca.pem=./path/to/downloaded-rds-ca.pem
kubectl apply -f deploy/ack/configmap.yaml
kubectl apply -f deploy/ack/secrets.example.yaml # 仅作模板;先替换全部占位值
kubectl apply -f deploy/ack/migration-job.yaml
kubectl -n zhinian wait --for=condition=complete job/zhinian-db-migrate --timeout=5m
kubectl apply -f deploy/ack/web.yaml -f deploy/ack/worker.yaml \
  -f deploy/ack/service.yaml -f deploy/ack/ingress.yaml

迁移 Job 运行 node scripts/migrate-postgres.mjs,读取镜像内 database/migrations/*.sql。迁移使用独立的 zhinian-migration-db Secret以便 授予建表/变更权限Web 的 zhinian-web-db 应只具有应用运行权限。每次发布先运行 迁移并确认成功,再滚动 Web。

首次把已有数据库纳入版本化迁移前必须先做 RDS 快照/逻辑备份,并在维护窗口执行。迁移器 遇到重复的历史 usage_events.job_id 会安全失败并要求人工审计,不会自动删除计费/用量 记录;清理后重新运行同一 Job。

替换模板占位符后,可先运行 npm run deploy:check 做仓库内静态契约检查;真正发布前仍需 使用目标 ACK 集群的 kubectl apply --dry-run=server 验证 CRD/准入策略和 Ingress 行为。

ACK 中的 Secret/ConfigMap 才是配置事实来源。不要在 /settings 页面修改生产密钥:该 页面写入容器内 .env.localPod 重建会丢失,也不会自动更新 Kubernetes Secret。应修改 Secret/ConfigMap 后触发 Deployment 滚动更新。

模板默认 Web 为 1 副本,因为仅启用 PostgreSQL 并不会共享上传/生成文件。确认这些文件 已使用 OSS 或其他共享对象存储后,才可水平扩容;本地 .runtime 数据或文件不能在副本 之间共享。Worker 只持有内部 token 并调用集群内 zhinian-web Service不持有 DATABASE_URL。Ingress 通过更长的 /api/internal/worker Prefix 把公网请求路由到 没有 Endpoint 的 zhinian-public-deny Service因此不会把内部接口转发给 Web也可以 在 API Gateway/WAF 再配置等价拒绝规则。不要默认添加依赖 Terway 或特定 ACK 托管组件 的 webhook/白名单注解。

探针约定:/api/health 是不查询数据库的进程存活检查;/api/ready 会确认 PostgreSQL 关键表存在,并验证应用角色具备任务表读写和两个业务函数的执行权限,失败返回 503。 启动探针避免迁移/冷启动期间过早重启。Worker 每次内部 tick 默认 120 秒超时,避免网络 半开连接让轮询进程永久卡住;可用 ZHINIAN_WORKER_REQUEST_TIMEOUT_MS 调整。

连接预算按 Web 副本数 × DATABASE_POOL_MAX 计算,并为迁移、管理连接和故障切换 预留余量。滚动更新默认可能短暂同时存在旧、新 Pod模板将 maxSurge 设为 1容量 预算至少覆盖 (replicas + 1) × pool max,否则应降低 pool 或使用 maxSurge: 0

当前 Docker runner 默认以 Node Alpine 镜像的 root 用户运行,模板没有虚构一个未经 镜像验证的 UID。生产加固应在镜像中创建固定非 root 用户、修正 /app/.runtime 权限, 验证写入与启动后,再把 Pod 设置为 runAsNonRoot: true

关键数据库变量:

变量 说明
ZHINIAN_DATA_BACKEND 生产固定为 postgres;配置错误不会降级到本地 JSON
DATABASE_URL PostgreSQL URI仅存 Secret不要写入镜像、ConfigMap 或日志
DATABASE_APP_ROLE 迁移 Job 使用;与 Web 的 RDS 用户名一致,用于授予最小应用权限
DATABASE_SSL_MODE disableverify-fullRDS SSL 生产建议 verify-full
DATABASE_CA_CERT_PATH 已挂载 CA 文件路径
DATABASE_POOL_MAX 单个 Web Pod 最大连接数
DATABASE_CONNECTION_TIMEOUT_MS 建连超时;模板为 5000 ms
DATABASE_IDLE_TIMEOUT_MS 空闲连接回收时间
DATABASE_STATEMENT_TIMEOUT_MS SQL 语句超时

NEXT_PUBLIC_SUPABASE_URLNEXT_PUBLIC_SUPABASE_ANON_KEYSUPABASE_SERVICE_ROLE_KEY 已废弃,直连 PostgreSQL 路径不会读取它们。

本文面向运维部署。推荐使用 Docker Compose同一套编排会启动 Web 服务和任务 Worker。

服务器要求

  • Linux 服务器
  • Docker
  • Docker Compose v2docker compose)或旧版 docker-compose
  • 可访问外网供应商接口:火山 Visual、EvoLink、Seedance、OSS

一键部署

git clone <仓库地址>
cd NianAIGC
bash scripts/deploy.sh

脚本会自动:

  • .env.example 创建 .env.local(如果不存在)
  • 创建 .runtime/data.runtime/uploads.runtime/generated-results
  • 创建 .runtime/logs
  • 构建镜像
  • 启动 zhinian-aigc Web 服务
  • 启动 zhinian-worker 任务 Worker
  • 输出容器状态

默认访问:

http://服务器IP:3000

必填生产配置

部署前编辑 .env.local

APP_PORT=3000
PORT=3000
HOSTNAME=0.0.0.0
NEXT_PUBLIC_APP_URL=https://你的域名

ZHINIAN_AUTH_REQUIRED=auto
ZHINIAN_AUTH_SESSION_SECRET=请替换为强随机会话密钥
ZHINIAN_DATA_BACKEND=postgres
DATABASE_URL=postgresql://应用账号:密码@RDS内网地址:5432/数据库名
DATABASE_SSL_MODE=verify-full
DATABASE_CA_CERT_PATH=/etc/zhinian/rds/ca.pem

ZHINIAN_API_KEYS=partner-a:请替换为强随机key
ZHINIAN_INTERNAL_WORKER_TOKEN=请替换为强随机token
ZHINIAN_WEBHOOK_SECRET=请替换为webhook签名密钥

ZHINIAN_API_KEYS 冒号前是开放 API 账号 ID。不同账号 ID 的任务、素材和幂等键会写入不同 owner 分区,例如 api:partner-a

真实生成能力按需配置:

IMAGE_GENERATE_ENGINE=evolink

EVOLINK_API_KEY=

VOLCENGINE_ACCESS_KEY_ID=
VOLCENGINE_SECRET_ACCESS_KEY=

SEEDANCE_API_KEY=

ALI_OSS_ENDPOINT=
ALI_OSS_BUCKET=
ALI_OSS_ACCESS_KEY_ID=
ALI_OSS_ACCESS_KEY_SECRET=
ALI_OSS_PUBLIC_BASE_URL=

如果不配置真实供应商密钥mock 配置会保留本地验收能力,但生产对接应配置真实密钥。

平台账号部署说明:

npm run bootstrap:admin -- --phone 13800138000 --password '请替换为强密码' --name '平台超级管理员'

生产部署前设置 DATABASE_APP_ROLE 并执行 npm run db:migrate,然后运行一次超级管理员 初始化命令。迁移器只向该应用角色显式授予当前业务表 DML 和两个数据库函数 EXECUTE 不会授予未来对象的默认权限、schema_migrations 或 DDL 权限。新增表/函数时必须随对应 版本迁移显式更新授权。旧账号使用 npm run migrate:accounts -- path/to/legacy-accounts.json 导入;迁移会保留用量并把历史 素材、任务、项目和模板映射到平台账号。

旧版组织账号接口(已停用)

如需启用 /accounts 后台账号管理,按组织能力接口文档配置:

ZHINIAN_ORG_API_BASE_URL=https://<gateway-domain>/hotelStaff
ZHINIAN_ORG_API_TOKEN=
ZHINIAN_STAFF_API_BASE_URL=https://<gateway-domain>/hotelStaff
ZHINIAN_STAFF_API_TOKEN=
ZHINIAN_ORG_TENANT_ID=
ZHINIAN_ORG_ID=
ZHINIAN_ORG_MEMBER_LIST_PATH=

平台后端会代理调用组织、部门、角色、成员和企业端用户接口;成员分页列表默认通过 hotelStaff/adminOrganization/organizationMember/organizationMemberList 对外代理,只有直连基础组织服务内部 /organizationMember/organizationMemberList 时才需要 from: Y。如统一服务路径不同,可配置 ZHINIAN_ORG_MEMBER_LIST_PATH 覆盖。创建账号调用 /adminOrganization/organizationMember/addOrganizationMemberAndCreatePlatformUser,重置密码调用 /adminPcUser/resetPlatformUserPassword。这些接口默认转发当前登录管理员账号的 access_token,企业端用户接口会校验该 token 是否具备管理员角色 1ZHINIAN_ORG_API_TOKEN / ZHINIAN_STAFF_API_TOKEN 只作为无登录 token 时的服务端兜底。

常用运维命令

docker compose ps
docker compose logs -f zhinian-aigc
docker compose logs -f zhinian-worker
docker compose restart
docker compose down

Web 后台可在登录后访问:

https://你的域名/logs
https://你的域名/settings
https://你的域名/accounts
https://你的域名/usage
https://你的域名/billing

日志默认写入 .runtime/logs/server-events.jsonl,用于查看 API 500 错误、Worker 任务异常、错误栈和请求路径。可通过环境变量 ZHINIAN_LOG_DIR 调整目录,通过 ZHINIAN_LOG_MAX_BYTES 调整单文件轮转大小。

更新部署:

git pull
bash scripts/deploy.sh

健康检查:

curl -f http://127.0.0.1:${APP_PORT:-3000}/api/health

OpenAPI

curl http://127.0.0.1:${APP_PORT:-3000}/api/v1/openapi.json

数据持久化

Docker Compose 会挂载:

./.runtime:/app/.runtime

本地 JSON 数据层、上传文件和生成结果都会放在 .runtime/ 下。local 仅适合单实例开发;如临时使用,必须备份该目录。 服务端日志也会放在 .runtime/logs/ 下,建议和运行时数据一起备份或接入服务器日志采集。

生产 PostgreSQL 发布前必须执行 npm run db:migrate,或先完成 ACK 的 zhinian-db-migrate Job。迁移器使用版本记录、校验和、事务和 advisory lock迁移成功后再滚动 Web。首次打开 /billing 或提交真实任务时,系统会自动导入内置标准成本目录;平台参数档案会同步,已有倍率会保留,超级管理员只维护上浮倍率。

建议备份:

tar -czf zhinian-runtime-$(date +%Y%m%d%H%M%S).tar.gz .runtime

服务组成

  • zhinian-aigcNext.js Web/API 服务,默认容器端口 3000
  • zhinian-worker:后台任务 Worker负责提交供应商任务、轮询结果、导入资产和触发 Webhook

注意:只启动 Web 服务时,任务会停留在 queuedrunning,必须同时运行 Worker。

反向代理建议

Nginx 示例:

server {
  listen 80;
  server_name your-domain.com;

  client_max_body_size 100m;

  location / {
    proxy_pass http://127.0.0.1:3000;
    proxy_set_header Host $host;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
  }
}

配置反向代理后,将 .env.local 里的 NEXT_PUBLIC_APP_URL 设置成公网 HTTPS 地址。

验收清单

部署后执行:

curl -f https://你的域名/api/health
curl -H "Authorization: Bearer <API_KEY>" https://你的域名/api/v1/capabilities
curl https://你的域名/api/v1/openapi.json

确认:

  • 未登录访问 Web 页面会跳转到 /auth/login
  • 普通用户登录后看到创作、账号和计费;账号页可修改自己的密码,任务详情、输入要素和结果下载均在创作页右侧任务模块完成,点击页头账号 ID 可查看自己的快捷周期用量
  • 从管理员入口登录且命中管理员账号或专用角色白名单后,可访问 /logs/settings/usage,并在 /accounts 额外维护组织和成员;超级管理员还可配置 /billing 计费规则和组织余额
  • /usage 可按日期、组织、账号、功能和服务商筛选Mock 与开放 API 任务不计入
  • /billing 可查看组织余额、成员消耗和账务流水;管理员通过“余额与上账”直接记入组织额度
  • /api/health 返回 ok: true
  • /logs 可查看后台错误日志
  • /api/v1/capabilities 使用 API Key 可访问
  • zhinian-worker 日志持续输出 claimed=...
  • OSS、EvoLink、火山、Seedance 密钥按业务需要配置完成