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>
This commit is contained in:
@@ -0,0 +1,4 @@
|
||||
# 基础设施机 128 的库密码。cp .env.example .env 后填写。
|
||||
# 这两个密码必须与 132 应用机 .env 里的 POSTGRES_PASSWORD / NEO4J_PASSWORD 一致。
|
||||
POSTGRES_PASSWORD=change-me-postgres
|
||||
NEO4J_PASSWORD=change-me-neo4j
|
||||
@@ -0,0 +1,134 @@
|
||||
# sundynix-agentix · 基础设施机 192.168.100.128
|
||||
#
|
||||
# cd deploy/128-infra && cp .env.example .env # 填库密码
|
||||
# docker compose up -d
|
||||
#
|
||||
# 说明:
|
||||
# - 对象存储 MinIO 已单独部署在 192.168.100.126,本机不含业务 MinIO;
|
||||
# 这里的 milvus-minio 仅供 Milvus 自己存段文件(内部网络,不对外)。
|
||||
# - 端口对局域网暴露(0.0.0.0),供应用机 192.168.100.132 连接。
|
||||
# ⚠️ Redis / Milvus / NATS 无认证,务必用防火墙只放行 132/126 网段,勿对公网开放。
|
||||
# - NATS 三节点集群(JetStream Raft):单机多容器,各自独立卷;对 132 暴露 4222/4223/4224。
|
||||
# 应用侧设 NATS_STREAM_REPLICAS=3,durable 流才有 quorum 容错。
|
||||
# - 全部卷持久化 + restart:unless-stopped,容器损坏/重启不丢数据。
|
||||
|
||||
services:
|
||||
# ---------- NATS 3 节点集群 ----------
|
||||
nats1:
|
||||
image: nats:2-alpine
|
||||
command: ["-c", "/etc/nats/nats-server.conf"]
|
||||
restart: unless-stopped
|
||||
volumes:
|
||||
- ../nats-cluster/nats1.conf:/etc/nats/nats-server.conf:ro
|
||||
- nats1_data:/data/jetstream
|
||||
ports: ["4222:4222", "8222:8222"] # 客户端 + 监控
|
||||
|
||||
nats2:
|
||||
image: nats:2-alpine
|
||||
command: ["-c", "/etc/nats/nats-server.conf"]
|
||||
restart: unless-stopped
|
||||
volumes:
|
||||
- ../nats-cluster/nats2.conf:/etc/nats/nats-server.conf:ro
|
||||
- nats2_data:/data/jetstream
|
||||
ports: ["4223:4222"]
|
||||
|
||||
nats3:
|
||||
image: nats:2-alpine
|
||||
command: ["-c", "/etc/nats/nats-server.conf"]
|
||||
restart: unless-stopped
|
||||
volumes:
|
||||
- ../nats-cluster/nats3.conf:/etc/nats/nats-server.conf:ro
|
||||
- nats3_data:/data/jetstream
|
||||
ports: ["4224:4222"]
|
||||
|
||||
# ---------- 关系库 / 缓存 ----------
|
||||
postgres:
|
||||
image: postgres:16-alpine
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
POSTGRES_USER: sundynix
|
||||
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:?需在 .env 设置}
|
||||
POSTGRES_DB: sundynix
|
||||
volumes: ["pg_data:/var/lib/postgresql/data"]
|
||||
ports: ["5432:5432"]
|
||||
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"]
|
||||
ports: ["6379:6379"]
|
||||
|
||||
# ---------- 向量库 Milvus(自带 etcd + 自带内部 minio,不复用 126)----------
|
||||
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"]
|
||||
|
||||
milvus-minio:
|
||||
image: minio/minio:RELEASE.2023-03-20T20-16-18Z
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
MINIO_ACCESS_KEY: minioadmin # Milvus 段存储专用,内部网络不对外
|
||||
MINIO_SECRET_KEY: minioadmin
|
||||
command: minio server /minio_data
|
||||
volumes: ["milvus_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: milvus-minio:9000
|
||||
volumes: ["milvus_data:/var/lib/milvus"]
|
||||
ports: ["19530:19530"] # 供 132 的 mcp-go 连接
|
||||
healthcheck:
|
||||
test: ["CMD", "curl", "-f", "http://localhost:9091/healthz"]
|
||||
interval: 15s
|
||||
timeout: 10s
|
||||
retries: 10
|
||||
depends_on: [milvus-etcd, milvus-minio]
|
||||
|
||||
# ---------- 图谱库 ----------
|
||||
neo4j:
|
||||
image: neo4j:5-community
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
NEO4J_AUTH: neo4j/${NEO4J_PASSWORD:?需在 .env 设置}
|
||||
volumes: ["neo4j_data:/data"]
|
||||
ports: ["7687:7687", "7474:7474"] # bolt + 浏览器
|
||||
|
||||
# ---------- 链路追踪(可选,不需要可删)----------
|
||||
jaeger:
|
||||
image: jaegertracing/all-in-one:1.60
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
COLLECTOR_OTLP_ENABLED: "true"
|
||||
ports: ["16686:16686", "4318:4318"] # UI + OTLP/HTTP 接收
|
||||
|
||||
volumes:
|
||||
nats1_data:
|
||||
nats2_data:
|
||||
nats3_data:
|
||||
pg_data:
|
||||
redis_data:
|
||||
milvus_etcd:
|
||||
milvus_minio_data:
|
||||
milvus_data:
|
||||
neo4j_data:
|
||||
@@ -0,0 +1,26 @@
|
||||
# 应用机 132 的密钥与凭据。cp .env.example .env 后填写(.env 不进 git)。
|
||||
# 三个应用服务共享 SUNDYNIX_SECRET_KEY,必须完全一致(否则跨服务密文解不开)。
|
||||
|
||||
# —— 引导密钥(生成:openssl rand -base64 32)——
|
||||
SUNDYNIX_SECRET_KEY=change-me-secret-32
|
||||
JWT_SECRET=change-me-jwt-32
|
||||
|
||||
# —— 库密码(须与 128-infra/.env 一致)——
|
||||
POSTGRES_PASSWORD=change-me-postgres
|
||||
NEO4J_PASSWORD=change-me-neo4j
|
||||
|
||||
# —— 对象存储(126 上的 MinIO 凭据)——
|
||||
MINIO_ACCESS_KEY=change-me-minio-access
|
||||
MINIO_SECRET_KEY=change-me-minio-secret
|
||||
MINIO_BUCKET=sundynix-docs
|
||||
|
||||
# —— 管理员白名单:首次注册后拿 user.id 填这里,重启 gateway 生效(逗号分隔多个)——
|
||||
ADMIN_USER_IDS=
|
||||
|
||||
# —— CORS:admin 同源免;桌面端/web 从 3000 跨源直连需填实际 origin(frp 外网域名等),
|
||||
# 生产(APP_ENV=production)下缺省不放行任意源。多个逗号分隔。——
|
||||
CORS_ALLOW_ORIGIN=
|
||||
|
||||
# —— 可选调参 ——
|
||||
DISPATCHER_CONCURRENCY=8
|
||||
TASK_TOKEN_BUDGET=200000
|
||||
@@ -0,0 +1,80 @@
|
||||
# sundynix-agentix · 应用机 192.168.100.132
|
||||
#
|
||||
# cd deploy/132-app && cp .env.example .env # 填密钥/密码/MinIO 凭据
|
||||
# docker compose up -d --build # 在 132 本地构建并运行(Gitea 自动部署也走这条)
|
||||
#
|
||||
# 说明:
|
||||
# - 对外只暴露 gateway:3000(frp 映射)。gateway 已内嵌 admin 控制台(同源 serve UI+API),
|
||||
# 无需单独 admin nginx 容器。dispatcher/mcp-go/mcp-py 只走 NATS,无对外端口。
|
||||
# - 基础设施在 128(PG/NATS集群/Redis/Milvus/Neo4j),对象存储在 126(MinIO),env 全部指向它们。
|
||||
# - 构建上下文为仓库根(../..,因 Go 服务 replace ../sundynix-shared)。
|
||||
# - NATS_STREAM_REPLICAS=3:durable 流走 128 三节点集群,有 Raft quorum 容错。
|
||||
|
||||
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://192.168.100.128:4222,nats://192.168.100.128:4223,nats://192.168.100.128:4224
|
||||
NATS_STREAM_REPLICAS: "3"
|
||||
POSTGRES_DSN: postgres://sundynix:${POSTGRES_PASSWORD:?}@192.168.100.128:5432/sundynix?sslmode=disable
|
||||
REDIS_ADDR: 192.168.100.128:6379
|
||||
MINIO_ENDPOINT: 192.168.100.126:9000
|
||||
MINIO_ACCESS_KEY: ${MINIO_ACCESS_KEY:?}
|
||||
MINIO_SECRET_KEY: ${MINIO_SECRET_KEY:?}
|
||||
MINIO_BUCKET: ${MINIO_BUCKET:-sundynix-docs}
|
||||
SUNDYNIX_SECRET_KEY: ${SUNDYNIX_SECRET_KEY:?}
|
||||
JWT_SECRET: ${JWT_SECRET:?}
|
||||
ADMIN_USER_IDS: ${ADMIN_USER_IDS:-}
|
||||
CORS_ALLOW_ORIGIN: ${CORS_ALLOW_ORIGIN:-*}
|
||||
OTEL_EXPORTER_OTLP_ENDPOINT: http://192.168.100.128:4318
|
||||
ports: ["3000:8080"] # frp 外网 → 132:3000 → 容器 8080
|
||||
|
||||
dispatcher:
|
||||
build: { context: ../.., dockerfile: sundynix-dispatcher/Dockerfile }
|
||||
image: sundynix/dispatcher:${TAG:-latest}
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
APP_ENV: production
|
||||
NATS_URL: nats://192.168.100.128:4222,nats://192.168.100.128:4223,nats://192.168.100.128:4224
|
||||
NATS_STREAM_REPLICAS: "3"
|
||||
SUNDYNIX_SECRET_KEY: ${SUNDYNIX_SECRET_KEY:?}
|
||||
OTEL_EXPORTER_OTLP_ENDPOINT: http://192.168.100.128:4318
|
||||
DISPATCHER_CONCURRENCY: ${DISPATCHER_CONCURRENCY:-8}
|
||||
TASK_TOKEN_BUDGET: ${TASK_TOKEN_BUDGET:-200000}
|
||||
|
||||
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://192.168.100.128:4222,nats://192.168.100.128:4223,nats://192.168.100.128:4224
|
||||
NATS_STREAM_REPLICAS: "3"
|
||||
POSTGRES_DSN: postgres://sundynix:${POSTGRES_PASSWORD:?}@192.168.100.128:5432/sundynix?sslmode=disable
|
||||
REDIS_ADDR: 192.168.100.128:6379
|
||||
MILVUS_ADDR: 192.168.100.128:19530
|
||||
NEO4J_URI: neo4j://192.168.100.128:7687
|
||||
NEO4J_USER: neo4j
|
||||
NEO4J_PASS: ${NEO4J_PASSWORD:?}
|
||||
# 报告源/产物 + KB 正文对象存储(本会话新加 blob)——指向 126,勿漏,否则 fallback localhost 连不上。
|
||||
MINIO_ENDPOINT: 192.168.100.126:9000
|
||||
MINIO_ACCESS_KEY: ${MINIO_ACCESS_KEY:?}
|
||||
MINIO_SECRET_KEY: ${MINIO_SECRET_KEY:?}
|
||||
MINIO_BUCKET: ${MINIO_BUCKET:-sundynix-docs}
|
||||
SUNDYNIX_SECRET_KEY: ${SUNDYNIX_SECRET_KEY:?}
|
||||
OTEL_EXPORTER_OTLP_ENDPOINT: http://192.168.100.128:4318
|
||||
|
||||
mcp-py:
|
||||
build: { context: ../../sundynix-mcp-py, dockerfile: Dockerfile }
|
||||
image: sundynix/mcp-py:${TAG:-latest}
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
NATS_URL: nats://192.168.100.128:4222,nats://192.168.100.128:4223,nats://192.168.100.128:4224
|
||||
# secure_sandbox(代码隔离执行)需访问宿主 Docker 拉一次性容器。安全敏感:等于把 132 宿主
|
||||
# Docker 暴露给该服务(可逃逸);不需要代码执行工具可注释掉这两行。mcp-py 无对外端口。
|
||||
volumes:
|
||||
- /var/run/docker.sock:/var/run/docker.sock
|
||||
@@ -0,0 +1,21 @@
|
||||
# NATS 集群节点 1 / 3(JetStream Raft)。单机多节点:三容器同宿主(128),各自独立卷。
|
||||
# 三节点的 max_payload 必须一致;server_name 唯一;routes 指向另外两节点的 cluster 端口。
|
||||
server_name: nats1
|
||||
port: 4222
|
||||
http_port: 8222
|
||||
max_payload: 8MB
|
||||
|
||||
jetstream {
|
||||
store_dir: "/data/jetstream"
|
||||
max_memory_store: 1GB
|
||||
max_file_store: 10GB
|
||||
}
|
||||
|
||||
cluster {
|
||||
name: sundynix-cluster
|
||||
listen: 0.0.0.0:6222
|
||||
routes: [
|
||||
nats-route://nats2:6222
|
||||
nats-route://nats3:6222
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
# NATS 集群节点 2 / 3(JetStream Raft)。max_payload 与其余节点一致;routes 指向 nats1/nats3。
|
||||
server_name: nats2
|
||||
port: 4222
|
||||
http_port: 8222
|
||||
max_payload: 8MB
|
||||
|
||||
jetstream {
|
||||
store_dir: "/data/jetstream"
|
||||
max_memory_store: 1GB
|
||||
max_file_store: 10GB
|
||||
}
|
||||
|
||||
cluster {
|
||||
name: sundynix-cluster
|
||||
listen: 0.0.0.0:6222
|
||||
routes: [
|
||||
nats-route://nats1:6222
|
||||
nats-route://nats3:6222
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
# NATS 集群节点 3 / 3(JetStream Raft)。max_payload 与其余节点一致;routes 指向 nats1/nats2。
|
||||
server_name: nats3
|
||||
port: 4222
|
||||
http_port: 8222
|
||||
max_payload: 8MB
|
||||
|
||||
jetstream {
|
||||
store_dir: "/data/jetstream"
|
||||
max_memory_store: 1GB
|
||||
max_file_store: 10GB
|
||||
}
|
||||
|
||||
cluster {
|
||||
name: sundynix-cluster
|
||||
listen: 0.0.0.0:6222
|
||||
routes: [
|
||||
nats-route://nats1:6222
|
||||
nats-route://nats2:6222
|
||||
]
|
||||
}
|
||||
Reference in New Issue
Block a user