部署架构
理解 Clouisle 服务拓扑、请求路由、依赖和持久化数据
Clouisle 使用 3 个镜像运行 5 个应用服务。clouisle-backend 提供 api、worker 和 beat;clouisle-sandbox-worker 提供 sandbox-worker;clouisle-frontend 提供 Next.js 前端。
服务拓扑
| 服务 | 镜像 | 作用 | 端口 |
|---|---|---|---|
frontend | clouisle-frontend | Next.js standalone server | 3000 |
api | clouisle-backend | FastAPI API | 8000 |
worker | clouisle-backend | Celery default、agent、knowledge、workflow 队列 | 无 |
sandbox-worker | clouisle-sandbox-worker | Celery sandbox 队列与产物上传 | 无 |
beat | clouisle-backend | Celery Beat 调度器,必须单副本 | 无 |
db | PostgreSQL 17 + pg_search | 业务、全文检索和审计数据 | 5432 |
redis | Redis 7 | 队列、缓存、会话 | 6379 |
qdrant | Qdrant 1.18.3 | 向量索引 | 6333 |
Celery 队列划分
clouisle-backend 镜像用子命令启动 api、worker、beat。任务到队列的映射在 backend/app/core/celery.py 的 task_routes 中静态声明,队列名以 -Q 指定。
| 队列 | 消费服务 | 任务模块 | 承载的工作 |
|---|---|---|---|
default | worker | app.tasks.usage、notification、audit_log、api_key、password_expiration、memory | 用量重置、通知投递、审计日志归档、API Key 与密码到期检查 |
agent | worker | app.tasks.agent | AgentRun 执行(模型调用与工具循环) |
knowledge | worker | app.tasks.knowledge_base | 文档解析、分块、嵌入与索引 |
workflow | worker | app.tasks.workflow | 工作流运行 |
sandbox | sandbox-worker | app.tasks.sandbox、tasks.cleanup_expired_sandbox_sessions | 代码沙箱执行与过期沙箱会话清理 |
官方 Compose、Helm 和单文件 manifest 的 worker 命令为 python main.py worker -c 4 -Q default,agent,knowledge,workflow,即一个服务同时消费 4 个队列;sandbox-worker 命令为 python main.py sandbox-worker -c <SANDBOX_WORKER_CONCURRENCY>,只消费 sandbox。
Beat 投递的周期性任务:sweep-lost-agent-runs 每 2 分钟一次到 default 队列(回收 worker 崩溃后仍处于运行中的 AgentRun,是 INTERRUPTED 状态的唯一来源),cleanup-expired-sandbox-sessions 每 15 分钟一次到 sandbox 队列。agent 队列任务不配置重试:模型调用和工具执行有副作用,重试会重复执行。
扩展规则:
docker compose up -d --scale worker=4或kubectl scale deployment worker会同时扩展全部 4 个队列。需要按队列独立扩展时,运行额外的 Worker 容器并只订阅一个队列,例如-Q agent单独扩容 AgentRun 执行。sandbox队列独立成服务,扩容sandbox-worker不会影响知识库与工作流处理。beat始终单副本,见服务拓扑。
请求路由
外部反向代理或 Ingress 负责路由:/api/* 到 api:8000,其余 / 到 frontend:3000。前端镜像不包含 Nginx;deploy/nginx/default.conf 只是可选的外部示例。
两条链路要分开理解:
- 浏览器 → API:浏览器请求
NEXT_PUBLIC_API_URL(前端镜像构建期默认/api/v1,即相对路径),由反向代理/Ingress 的/api前缀转发到api:8000。Compose 中前端服务本身也用 Next.js rewrites 把/api/*转发到BACKEND_INTERNAL_URL。 - Next.js 服务端 → API:
BACKEND_INTERNAL_URL拼接基路径。代码默认http://localhost:8000,Compose 注入http://api:8000,K8s 单文件 manifest 与 Helm 默认的frontend工作负载不带任何环境变量。
后端所有路由挂载在 API_V1_STR 之下,默认 /api/v1:GET {API_V1_STR}/health、{API_V1_STR}/openapi.json 都会随之改变。改动该值时,代理/Ingress 路径与前端构建期 NEXT_PUBLIC_API_URL 必须同步改成相同的 /api/v1 前缀,否则浏览器与服务端取数都会打到不存在的路径。
持久化数据
Compose 默认卷:postgres_data、redis_data、qdrant_data 和 uploads_data。多 API 副本使用本地上传存储时需要 ReadWriteMany;只有 ReadWriteOnce 时保持一个 API 副本,Worker 和 Sandbox Worker 仍可独立扩展。
内部地址
容器内使用服务名,不要使用 localhost:
| 变量 | Compose / K8s 取值 | 用途 |
|---|---|---|
POSTGRES_SERVER | db / postgres | 数据库 |
REDIS_HOST | redis | 缓存与 Celery broker/backend |
QDRANT_URL | http://qdrant:6333 | 向量库 |
API_BASE_URL | http://api:8000 | 服务端内部 API 地址 |
API_INTERNAL_BASE_URL | http://api:8000 | Worker 经此访问上传网关(UPLOAD_STORAGE_MODE=remote) |
SANDBOX_ARTIFACT_UPLOAD_BASE_URL | http://api:8000 | Sandbox Worker 产物上传 |
K8s 中 FRONTEND_URL 设为 http://frontend:3000(SSO 回调基址),并由 clouisle-secret 提供 INTERNAL_API_TOKEN,Pod 内通过 INTERNAL_API_TOKEN_FILE=/var/run/secrets/clouisle/internal-api-token 读取。Worker 与 Sandbox Worker 不挂 uploads 卷,而是走这条内部网关。
这篇文章对你有帮助吗?