跳转至

部署

本文档同时覆盖两种部署方式:

  1. 本地/自建 VM 方式(Docker Compose)
  2. GitHub Actions CI/CD 方式(推送镜像 + 环境发布)

本地 Docker Compose(开发与联调)

项目包含两个 Docker Compose 文件,用于分离基础设施与应用服务。

首先启动基础设施服务:

just docker-infra

或手动执行:

docker network create chameleon-net
docker compose -f docker-compose.infra.yml up -d

然后启动应用服务:

docker compose up -d --build

默认端口映射:

  • AI 服务:8000
  • Demo 后端:3000
  • Demo 前端:80
  • Docs 站点:8001
  • MinIO:9000
  • MinIO Console:9001
  • Qdrant:6333
  • PostgreSQL:5432
  • pgAdmin:5050
  • RedisInsight:5540

中间件管理界面

各中间件提供 Web 管理界面,用于浏览和管理内部资源(数据库表、缓存键、向量集合、对象存储桶等)。

服务 地址 默认账号
pgAdmin(PostgreSQL) http://localhost:5050 邮箱:PGADMIN_DEFAULT_EMAIL(默认 admin@admin.com
密码:PGADMIN_DEFAULT_PASSWORD(默认 admin
RedisInsight(Redis) http://localhost:5540 无需登录
Qdrant Dashboard http://localhost:6333/dashboard 无需登录
MinIO Console http://localhost:9001 用户:MINIO_ROOT_USER
密码:MINIO_ROOT_PASSWORD

pgAdmin 连接 PostgreSQL

首次登录 pgAdmin 后,需手动添加服务器连接:

  • Hostpostgres
  • Port5432
  • Username.env 中的 POSTGRES_USER
  • Password.env 中的 POSTGRES_PASSWORD

RedisInsight 连接 Redis

首次打开 RedisInsight 后,手动添加 Redis 连接:

  • Hostredis
  • Port6379

容器间通信

  • ai-servicedemo-backend 通过外部网络 chameleon-net 通信。
  • 本地 docker-compose.yml 未包含 Admin 前端;但已包含 docs-site,默认映射到宿主机 8001 端口。
  • CI/CD 发布清单 docker-compose.deploy.yml 包含 admin-frontenddocs-site 服务。
  • docker-compose.deploy.yml 面向 Dokploy,使用内部网络 + expose,不对宿主机直接发布端口。
  • docker-compose.deploy.ymlai-service 使用命名卷 ai_service_data(而非 ./data/./config.toml/./resources bind),避免 Swarm 节点路径不存在导致任务被拒绝。
  • docker-compose.deploy.ymlai-service 同时加入 dokploy-public 网络,便于在 Dokploy 直接为 API 配置域名路由。

Dokploy 单机部署(环境变量与 Domain)

以下变量用于 docker-compose.deploy.yml。在 Dokploy 中可配置在项目的 Environment Variables。

必填变量

变量名 用途 示例
AI_SERVICE_IMAGE ai-service 镜像地址 registry.zata.cafe/aibot/ai-service:<tag>
DEMO_BACKEND_IMAGE demo-backend 镜像地址 registry.zata.cafe/aibot/demo-backend:<tag>
DEMO_FRONTEND_IMAGE demo-frontend 镜像地址 registry.zata.cafe/aibot/demo-frontend:<tag>
ADMIN_FRONTEND_IMAGE admin-frontend 镜像地址 registry.zata.cafe/aibot/admin-frontend:<tag>
DOCS_SITE_IMAGE docs-site 镜像地址 registry.zata.cafe/aibot/docs-site:<tag>

强烈建议显式配置(不要使用默认值)

变量名 用途
POSTGRES_USER PostgreSQL 用户名
POSTGRES_PASSWORD PostgreSQL 密码
POSTGRES_DB PostgreSQL 数据库名
DATABASE_URL ai-service 数据库连接串,建议与上面三项保持一致
MINIO_ROOT_USER MinIO 管理账号
MINIO_ROOT_PASSWORD MinIO 管理密码
MINIO_ACCESS_KEY ai-service 访问 MinIO 的 Access Key,建议与 MINIO_ROOT_USER 一致
MINIO_SECRET_KEY ai-service 访问 MinIO 的 Secret Key,建议与 MINIO_ROOT_PASSWORD 一致
DASHSCOPE_API_KEY DashScope 模型调用密钥(如使用)
OPENROUTER_API_KEY OpenRouter 模型调用密钥(如使用)

可选变量

变量名 默认值 说明
DOKPLOY_PUBLIC_NETWORK dokploy-network Dokploy 外部网络名称
MINIO_ENDPOINT minio:9000 MinIO 容器内访问地址
QDRANT_HOST qdrant Qdrant 容器名
QDRANT_PORT 6333 Qdrant 端口

Dokploy Domain 推荐配置

Service Name Host(示例) Path Internal Path Strip Path Container Port
demo-frontend aibot.zata.cafe / / 关闭 80
demo-backend aibot.zata.cafe /api / 开启 3000
admin-frontend admin.aibot.zata.cafe / / 关闭 80
ai-service(Admin API 必需) admin.aibot.zata.cafe /api / 开启 8000
ai-service(可选直连) ai-api.aibot.zata.cafe / / 关闭 8000
docs-site docs.aibot.zata.cafe / / 关闭 80

注意事项:

  • demo-frontend 是 Nginx 静态站点,容器端口是 80;若填 3000 会导致 Bad Gateway
  • 前端固定通过 /api 与后端通信(含 Socket.IO 路径 /api/socket.io),所以 demo-backend 规则需使用 Path=/api 且开启 Strip Path
  • admin-frontend 也固定调用同域名 /api/*(如 /api/knowledge-sources),因此 admin.aibot.zata.cafe 需要同时配置两条规则:/ -> admin-frontend:80/api -> ai-service:8000Strip Path 开启)。
  • Strip Path 关闭,请求会以 /api/knowledge-sources 转发到 ai-service,而后端真实路由是 /knowledge-sources,会返回 404
  • docs-site 是 Nginx 静态站点,推荐使用独立域名(例如 docs.aibot.zata.cafe)直连容器 80 端口。
  • 修改 Domain 后,需要在 Dokploy 里重新部署 compose 才会生效。

自定义建议

  • 使用外部数据库时,请将 DATABASE_URL 指向托管实例。
  • 为模型 API Key 使用安全的密钥管理方案。
  • 多实例扩展场景下需确保 WebSocket 会话的一致性策略。
  • ai_service 生产镜像默认不安装 local_embedding 依赖组以减小体积;若需容器内本地 embedding,请在构建时设置 ENABLE_LOCAL_EMBEDDING=true

GitHub Actions CI/CD(主线发布)

工作流文件

  • CI:.github/workflows/ci.yml
  • CD:.github/workflows/cd.yml

触发规则

  • CI:对 main 的 Pull Request 自动触发
  • CD 发布main 分支 push 自动触发
  • CD 回滚:手动触发 workflow_dispatch 并填写 rollback_tag(即历史 Git SHA 镜像标签)

镜像仓库与标签策略

  • Registry Host:registry.zata.cafe
  • 默认命名空间:aibot(可通过 GitHub Repository Variable IMAGE_NAMESPACE 覆盖)
  • 每个服务发布两个标签:
  • 不可变标签:${GIT_SHA}
  • 滚动标签:main-latest

服务列表:

  • ai-service
  • demo-backend
  • demo-frontend
  • admin-frontend
  • docs-site
  • postgres
  • minio
  • qdrant
  • redis

必需 GitHub Secrets

Secret 用途 示例
REGISTRY_USERNAME 登录 registry.zata.cafe
REGISTRY_PASSWORD 登录 registry.zata.cafe
DOKPLOY_PROD_DEPLOY_HOOK 生产环境发布 webhook(手动审批后触发) http://zata.cafe:3000/api/deploy/compose/lFyKFKfELXOthpMRsNaea
PROD_HEALTHCHECK_URL 生产发布后健康检查地址 https://admin.aibot.zata.cafe/api/healthzhttps://ai-api.aibot.zata.cafe/healthz

可选:

Secret 用途 示例
DOKPLOY_STAGING_DEPLOY_HOOK 若配置则在 staging job 自动触发

环境门禁(Manual Approval)

  • 在 GitHub 仓库创建 Environments:
  • staging
  • production
  • production 配置 Required reviewers,即可在 CD 中实现人工审批后发布。

发布流程(main push)

  1. 构建并推送 5 个服务镜像的不可变标签 ${GIT_SHA}registry.zata.cafe
  2. 校验 ${GIT_SHA} 标签在 registry 可见后,提升为滚动标签 main-latest
  3. 自动执行 staging 阶段(可选触发 Dokploy staging hook)
  4. 进入 production 环境审批
  5. 审批通过后触发 DOKPLOY_PROD_DEPLOY_HOOK
  6. 轮询 PROD_HEALTHCHECK_URL 直到通过或超时失败

回滚流程

方案 A:GitHub Actions 手动回滚(推荐)

  1. 打开 CD workflow 的 Run workflow
  2. 填写 rollback_tag(目标历史 SHA)
  3. 流程会将各服务 ${rollback_tag} 重新标记为 main-latest
  4. 自动触发生产 deploy hook 并执行健康检查

说明:若该历史 tag 尚未包含 docs-site 镜像,回滚流程会保留现有 docs-site:main-latest,不会阻塞其他核心服务回滚。

方案 B:VM 上执行 Compose 回滚脚本

仓库内提供脚本:

  • scripts/deploy/compose-deploy.sh
  • scripts/deploy/compose-rollback.sh

示例(部署指定 SHA):

IMAGE_TAG=<git_sha> ./scripts/deploy/compose-deploy.sh \
  --registry-host registry.zata.cafe \
  --image-namespace aibot

示例(回滚到上一个成功版本):

./scripts/deploy/compose-rollback.sh

脚本会在 .deploy-state/ 记录 current.env / previous.env,用于快速恢复。 若目标回滚元数据缺失 DOCS_SITE_IMAGE 或对应镜像不可用,脚本会优先保留当前 docs 镜像,不可用时再回退到 docs-site:main-latest