Files
sundynix-agentix/docker-compose.prod.yml
T
Blizzard 6b45adbbd2 chore(deploy): 三机部署 compose 拆分 + NATS 3 节点集群
126=MinIO(已部署)、128=基础设施、132=应用。

- deploy/128-infra:NATS 3 节点集群(独立卷+cluster routes,暴露4222/4223/4224)+PG/Redis/
  Milvus(自带etcd+自带内部minio,不复用126)/Neo4j/Jaeger;端口对局域网暴露、卷持久化。
- deploy/nats-cluster/nats{1,2,3}.conf:max_payload 一致 + jetstream + cluster。
- deploy/132-app:仅 gateway(3000:8080)+dispatcher+mcp-go+mcp-py,无 admin nginx;env 指向
  126/128;mcp-go 补齐 MINIO env(本会话 blob 遗漏);NATS_STREAM_REPLICAS=3;.env.example 模板。
- docker-compose.prod.yml(单机):删 admin 服务(已内嵌)、mcp-go 补 MINIO env。
- 三个 compose 均 docker compose config 校验通过;.env 已 gitignore、.env.example 可提交。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-18 14:45:24 +08:00

184 lines
6.6 KiB
YAML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# sundynix-agentix · 生产/独立部署编排(应用 + 基建一把拉起)
#
# cp .env.example .env # 然后按提示填密钥(见 DEPLOY.md)
# docker compose -f docker-compose.prod.yml up -d --build
#
# 设计:
# - 应用经服务名互连(postgres:5432 等),不依赖 127.0.0.1;基建端口不对宿主暴露(仅内网)。
# - 仅暴露 gateway(:${GATEWAY_PORT},内嵌 admin 控制台 + API + 供桌面端直连) + Jaeger UI(可选)。
# - 引导密钥从 .env 注入(SUNDYNIX_SECRET_KEY/JWT_SECRET/各库密码);模型 API key 仍在控制台配、加密存 PG。
# - APP_ENV=production → 强制校验密钥、锁 CORS、启用管理员白名单。
x-secret-key: &secret-key ${SUNDYNIX_SECRET_KEY:?需在 .env 设置(openssl rand -base64 32}
services:
# ---------- 应用层 ----------
gateway:
build: { context: ., dockerfile: sundynix-gateway/Dockerfile }
image: sundynix/gateway:${TAG:-latest}
restart: unless-stopped
environment:
APP_ENV: production
GATEWAY_ADDR: ":8080"
NATS_URL: nats://nats:4222
POSTGRES_DSN: postgres://sundynix:${POSTGRES_PASSWORD:?}@postgres:5432/sundynix?sslmode=disable
REDIS_ADDR: redis:6379
MINIO_ENDPOINT: minio:9000
MINIO_ACCESS_KEY: minioadmin # minio 仅 compose 内网可达,不对宿主暴露
MINIO_SECRET_KEY: minioadmin
SUNDYNIX_SECRET_KEY: *secret-key
JWT_SECRET: ${JWT_SECRET:?需在 .env 设置(openssl rand -base64 32}
ADMIN_USER_IDS: ${ADMIN_USER_IDS:-}
CORS_ALLOW_ORIGIN: ${CORS_ALLOW_ORIGIN:-*}
OTEL_EXPORTER_OTLP_ENDPOINT: http://jaeger:4318
ports: ["${GATEWAY_PORT:-8080}:8080"]
depends_on:
postgres: { condition: service_healthy }
redis: { condition: service_started }
nats: { condition: service_started }
dispatcher:
build: { context: ., dockerfile: sundynix-dispatcher/Dockerfile }
image: sundynix/dispatcher:${TAG:-latest}
restart: unless-stopped
environment:
APP_ENV: production
NATS_URL: nats://nats:4222
SUNDYNIX_SECRET_KEY: *secret-key
OTEL_EXPORTER_OTLP_ENDPOINT: http://jaeger:4318
DISPATCHER_CONCURRENCY: ${DISPATCHER_CONCURRENCY:-8}
TASK_TOKEN_BUDGET: ${TASK_TOKEN_BUDGET:-200000}
depends_on:
nats: { condition: service_started }
mcp-go:
build: { context: ., dockerfile: sundynix-mcp-go/Dockerfile }
image: sundynix/mcp-go:${TAG:-latest}
restart: unless-stopped
environment:
APP_ENV: production
NATS_URL: nats://nats:4222
POSTGRES_DSN: postgres://sundynix:${POSTGRES_PASSWORD:?}@postgres:5432/sundynix?sslmode=disable
REDIS_ADDR: redis:6379
MILVUS_ADDR: milvus:19530
NEO4J_URI: neo4j://neo4j:7687
NEO4J_USER: neo4j
NEO4J_PASS: ${NEO4J_PASSWORD:?}
# 报告源/产物 + KB 正文对象存储(blob)——与 gateway 同一 MinIO,勿漏否则 fallback localhost。
MINIO_ENDPOINT: minio:9000
MINIO_ACCESS_KEY: minioadmin
MINIO_SECRET_KEY: minioadmin
MINIO_BUCKET: sundynix-docs
SUNDYNIX_SECRET_KEY: *secret-key
OTEL_EXPORTER_OTLP_ENDPOINT: http://jaeger:4318
depends_on:
nats: { condition: service_started }
milvus: { condition: service_healthy } # mcp-go 须在 Milvus 后起,否则工具 no responders
mcp-py:
build: { context: sundynix-mcp-py, dockerfile: Dockerfile }
image: sundynix/mcp-py:${TAG:-latest}
restart: unless-stopped
environment:
NATS_URL: nats://nats:4222
# secure_sandbox(代码隔离执行)需访问宿主 Docker 拉起一次性容器。
# 安全敏感:等于把宿主 Docker 暴露给该服务;不需要代码执行工具可注释掉这行。
volumes:
- /var/run/docker.sock:/var/run/docker.sock
depends_on:
nats: { condition: service_started }
# admin 运维控制台已内嵌进 gatewaygo:embed,见 sundynix-gateway/internal/webui),
# 不再需要单独的 nginx 容器:访问 gateway:${GATEWAY_PORT} 即同时得到控制台 UI + API。
# ---------- 基础设施(端口不对宿主暴露,仅 compose 内网) ----------
nats:
image: nats:2-alpine
command: ["-c", "/etc/nats/nats-server.conf"]
restart: unless-stopped
volumes:
- ./deploy/nats/nats-server.conf:/etc/nats/nats-server.conf:ro
- nats_data:/data/jetstream
postgres:
image: postgres:16-alpine
restart: unless-stopped
environment:
POSTGRES_USER: sundynix
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:?}
POSTGRES_DB: sundynix
volumes: ["pg_data:/var/lib/postgresql/data"]
healthcheck:
test: ["CMD-SHELL", "pg_isready -U sundynix"]
interval: 5s
timeout: 5s
retries: 10
redis:
image: redis:7-alpine
restart: unless-stopped
volumes: ["redis_data:/data"]
jaeger:
image: jaegertracing/all-in-one:1.60
restart: unless-stopped
environment:
COLLECTOR_OTLP_ENABLED: "true"
ports: ["${JAEGER_UI_PORT:-16686}:16686"] # 链路追踪 UI(演示可看 span 瀑布图;不需要可去掉)
milvus-etcd:
image: quay.io/coreos/etcd:v3.5.14
restart: unless-stopped
environment:
ETCD_AUTO_COMPACTION_MODE: revision
ETCD_AUTO_COMPACTION_RETENTION: "1000"
ETCD_QUOTA_BACKEND_BYTES: "4294967296"
ETCD_SNAPSHOT_COUNT: "50000"
command: etcd -advertise-client-urls=http://127.0.0.1:2379 -listen-client-urls http://0.0.0.0:2379 --data-dir /etcd
volumes: ["milvus_etcd:/etcd"]
minio:
image: minio/minio:RELEASE.2023-03-20T20-16-18Z
restart: unless-stopped
environment:
MINIO_ACCESS_KEY: minioadmin # 内网专用(不对宿主暴露端口),与 milvus/gateway 默认对齐
MINIO_SECRET_KEY: minioadmin
command: minio server /minio_data
volumes: ["minio_data:/minio_data"]
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/live"]
interval: 30s
timeout: 20s
retries: 3
milvus:
image: milvusdb/milvus:v2.4.13
command: ["milvus", "run", "standalone"]
restart: unless-stopped
environment:
ETCD_ENDPOINTS: milvus-etcd:2379
MINIO_ADDRESS: minio:9000
volumes: ["milvus_data:/var/lib/milvus"]
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:9091/healthz"]
interval: 15s
timeout: 10s
retries: 10
depends_on: [milvus-etcd, minio]
neo4j:
image: neo4j:5-community
restart: unless-stopped
environment:
NEO4J_AUTH: neo4j/${NEO4J_PASSWORD:?}
volumes: ["neo4j_data:/data"]
volumes:
nats_data:
pg_data:
redis_data:
milvus_etcd:
minio_data:
milvus_data:
neo4j_data: