# ============================================================ # AgentCraft-Claw 全栈 Docker Compose 部署 # 包含:基础设施( MySQL + Redis + MinIO + Milvus ) + 后端 + 前端 + 可观测性( Prometheus + Grafana + Alertmanager ) # ============================================================ # # 用法: # 1. 首次启动: docker compose up -d --build # 2. 查看日志: docker compose logs -f backend # 3. 停止(保留数据): docker compose down # 4. 停止并清理数据(开发环境): docker compose down -v # 5. 仅基础设施: docker compose -f backend/docker-compose.dev.yml up -d # # 访问地址: # - 前端: http://localhost # - 后端: http://localhost/api # - MinIO: http://localhost:9003 (minioadmin / minioadmin,生产必须修改) # - Grafana: http://localhost:3000 (admin / admin,生产必须修改) # - Alertmanager: http://localhost:9093 # # 验证命令速查: # docker compose ps # 查看所有服务健康状态 # curl http://localhost/api/actuator/health # 后端健康检查 # curl http://localhost:9090/api/v1/targets # Prometheus targets # curl -X POST http://localhost:9093/-/reload # 重载 Alertmanager 配置 # curl http://localhost:9093/api/v2/status # Alertmanager 状态 # ============================================================ # 生产环境必须设置以下环境变量: # BAILIAN_API_KEY - 阿里云百炼 API Key(必填) # JWT_SECRET - 至少 32 字节的随机字符串(必填) # MYSQL_ROOT_PASSWORD - MySQL root 密码(建议修改) # MINIO_ROOT_PASSWORD - MinIO root 密码(建议修改) # 可选: # TAVILY_API_KEY, WEB_SEARCH_ENABLED, CORS_ALLOWED_ORIGINS # ALERT_EMAIL_*, DINGTALK_WEBHOOK_URL, WECHAT_WORK_WEBHOOK_URL, FEISHU_WEBHOOK_URL, SMS_WEBHOOK_URL networks: agentcraft_default: driver: bridge name: agentcraft_default agentcraft-claw_default: driver: bridge services: # ===== 基础设施 ===== mysql: image: mysql:8.0 container_name: agentcraft-mysql restart: unless-stopped networks: - agentcraft_default environment: MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD:-root} MYSQL_DATABASE: agentcraft MYSQL_CHARSET: utf8mb4 MYSQL_COLLATION: utf8mb4_unicode_ci volumes: - agentcraft_mysql_data:/var/lib/mysql - ./docs/agentcraft.sql:/docker-entrypoint-initdb.d/01-init.sql:ro ports: - "3307:3306" healthcheck: test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-u", "root", "-p${MYSQL_ROOT_PASSWORD:-root}"] interval: 10s timeout: 5s retries: 5 deploy: resources: limits: cpus: '2' memory: 2G redis: image: redis:7-alpine container_name: agentcraft-redis restart: unless-stopped networks: - agentcraft_default command: redis-server --save 60 1 --loglevel warning ${REDIS_PASSWORD:+--requirepass ${REDIS_PASSWORD}} volumes: - agentcraft_redis_data:/data ports: - "6380:6379" healthcheck: test: ["CMD-SHELL", "redis-cli ${REDIS_PASSWORD:+--pass ${REDIS_PASSWORD}} ping | grep PONG"] interval: 10s timeout: 5s retries: 5 deploy: resources: limits: cpus: '0.5' memory: 512M etcd: image: quay.io/coreos/etcd:v3.5.5 container_name: agentcraft-etcd restart: unless-stopped networks: - agentcraft_default 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://etcd:2379 --listen-client-urls=http://0.0.0.0:2379 --data-dir=/etcd volumes: - agentcraft_etcd_data:/etcd healthcheck: test: ["CMD", "etcdctl", "endpoint", "health"] interval: 10s timeout: 5s retries: 5 deploy: resources: limits: cpus: '0.5' memory: 256M minio: image: minio/minio:RELEASE.2024-06-29T01-20-47Z container_name: agentcraft-minio restart: unless-stopped networks: - agentcraft_default command: server /data --console-address ":9001" environment: MINIO_ROOT_USER: ${MINIO_ROOT_USER:-minioadmin} MINIO_ROOT_PASSWORD: ${MINIO_ROOT_PASSWORD:-minioadmin} volumes: - agentcraft_minio_data:/data ports: - "9002:9000" - "9003:9001" healthcheck: test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/live"] interval: 15s timeout: 5s retries: 5 deploy: resources: limits: cpus: '1' memory: 1G milvus: image: milvusdb/milvus:v2.3.4 container_name: agentcraft-milvus restart: unless-stopped networks: - agentcraft_default command: ["milvus", "run", "standalone"] environment: ETCD_ENDPOINTS: etcd:2379 MINIO_ADDRESS: minio:9000 volumes: - agentcraft_milvus_data:/var/lib/milvus ports: - "19530:19530" depends_on: etcd: condition: service_healthy minio: condition: service_healthy healthcheck: test: ["CMD", "curl", "-f", "http://localhost:9091/healthz"] interval: 15s timeout: 5s retries: 5 deploy: resources: limits: cpus: '2' memory: 4G # ===== 后端 ===== backend: build: context: ./backend dockerfile: Dockerfile container_name: agentcraft-backend restart: unless-stopped environment: # 数据库 MYSQL_HOST: mysql MYSQL_PORT: 3306 MYSQL_DATABASE: agentcraft MYSQL_USERNAME: root MYSQL_PASSWORD: ${MYSQL_ROOT_PASSWORD:-root} MYSQL_USE_SSL: "false" MYSQL_ALLOW_PUBLIC_KEY_RETRIEVAL: "true" # Redis REDIS_HOST: redis REDIS_PORT: 6379 REDIS_PASSWORD: ${REDIS_PASSWORD:-} # Milvus MILVUS_HOST: milvus MILVUS_PORT: 19530 # MinIO MINIO_ENDPOINT: http://minio:9000 MINIO_ACCESS_KEY: ${MINIO_ROOT_USER:-minioadmin} MINIO_SECRET_KEY: ${MINIO_ROOT_PASSWORD:-minioadmin} # 安全 JWT_SECRET: ${JWT_SECRET} CORS_ALLOWED_ORIGINS: ${CORS_ALLOWED_ORIGINS:-http://localhost} # LLM (必须替换为实际 API Key) BAILIAN_API_KEY: ${BAILIAN_API_KEY} OPENCLAW_API_KEY: ${OPENCLAW_API_KEY:-} # Tavily (可选,用于联网搜索) TAVILY_API_KEY: ${TAVILY_API_KEY:-} WEB_SEARCH_ENABLED: ${WEB_SEARCH_ENABLED:-false} # 日志级别 APP_LOG_LEVEL: ${APP_LOG_LEVEL:-INFO} # Loki 日志推送地址 LOKI_URL: http://loki:3100 # 性能优化配置 LLM_COST_MODELS: ${LLM_COST_MODELS:-qwen-plus=0.0005:0.0015,qwen-max=0.002:0.006,gpt-4o=0.018:0.054} LLM_BUDGET_ALERT_THRESHOLD: ${LLM_BUDGET_ALERT_THRESHOLD:-0.80} MASKING_ENABLED: ${MASKING_ENABLED:-true} MASKING_DEFAULT_LEVEL: ${MASKING_DEFAULT_LEVEL:-L2_API} HIKARI_MAX_POOL_SIZE: ${HIKARI_MAX_POOL_SIZE:-50} HIKARI_MIN_IDLE: ${HIKARI_MIN_IDLE:-10} # 链路追踪配置 JAEGER_ENDPOINT: ${JAEGER_ENDPOINT:-http://jaeger:4317} # Neo4j 图数据库 NEO4J_URI: ${NEO4J_URI:-bolt://neo4j:7687} NEO4J_USERNAME: ${NEO4J_USERNAME:-neo4j} NEO4J_PASSWORD: ${NEO4J_PASSWORD:-agentcraft} # Nacos 配置中心 NACOS_SERVER_ADDR: ${NACOS_SERVER_ADDR:-nacos:8848} NACOS_NAMESPACE: ${NACOS_NAMESPACE:-} NACOS_GROUP: ${NACOS_GROUP:-DEFAULT_GROUP} # RabbitMQ RABBITMQ_HOST: ${RABBITMQ_HOST:-rabbitmq} RABBITMQ_PORT: ${RABBITMQ_PORT:-5672} RABBITMQ_USERNAME: ${RABBITMQ_USERNAME:-agentcraft} RABBITMQ_PASSWORD: ${RABBITMQ_PASSWORD:-agentcraft} # Python AI 子服务 gRPC AI_SERVICE_GRPC_HOST: ${AI_SERVICE_GRPC_HOST:-python-ai-service} AI_SERVICE_GRPC_PORT: ${AI_SERVICE_GRPC_PORT:-50051} # Graph RAG 开关 GRAPHRAG_ENABLED: ${GRAPHRAG_ENABLED:-false} # Phase 3 智能化升级配置 HIERARCHICAL_MODEL_ENABLED: ${HIERARCHICAL_MODEL_ENABLED:-true} VLLM_PLANNER_URL: ${VLLM_PLANNER_URL:-http://vllm-planner:8000} VLLM_REVIEWER_URL: ${VLLM_REVIEWER_URL:-http://vllm-reviewer:8001} MODEL_TRAINER_URL: ${MODEL_TRAINER_URL:-http://model-training-service:8080} AGENTCRAFT_RL_ENABLED: ${AGENTCRAFT_RL_ENABLED:-false} NEGOTIATION_ENABLED: ${NEGOTIATION_ENABLED:-false} # Phase 4 平台化与商业化配置 TENANT_ENABLED: ${TENANT_ENABLED:-false} BILLING_ENABLED: ${BILLING_ENABLED:-false} API_KEY_ENABLED: ${API_KEY_ENABLED:-false} COLLABORATION_ENABLED: ${COLLABORATION_ENABLED:-false} TTS_ENABLED: ${TTS_ENABLED:-false} COMPLIANCE_ENABLED: ${COMPLIANCE_ENABLED:-false} WATERMARK_ENABLED: ${WATERMARK_ENABLED:-false} OPA_URL: ${OPA_URL:-http://opa:8181} # 高级/预留配置(需在 application.yml 中显式接入后生效) LOCAL_MODEL_BASE_URL: ${LOCAL_MODEL_BASE_URL:-http://localhost:8000/v1} TEI_BASE_URL: ${TEI_BASE_URL:-http://localhost:8080} MULTIMODAL_OCR_ENGINE: ${MULTIMODAL_OCR_ENGINE:-tesseract} MULTIMODAL_EMBEDDING_URL: ${MULTIMODAL_EMBEDDING_URL:-http://localhost:8080} SSO_ENABLED: ${SSO_ENABLED:-false} SSO_PROVIDER_TYPE: ${SSO_PROVIDER_TYPE:-oauth2} AGENT_INTEROP_CALLBACK_SECRET: ${AGENT_INTEROP_CALLBACK_SECRET:-} # 告警通知通道配置(Alertmanager 也会使用,但后端作为通用转发层同样需要) ALERT_EMAIL_SMTP_HOST: ${ALERT_EMAIL_SMTP_HOST:-} ALERT_EMAIL_SMTP_PORT: ${ALERT_EMAIL_SMTP_PORT:-} ALERT_EMAIL_TLS: ${ALERT_EMAIL_TLS:-true} ALERT_EMAIL_FROM: ${ALERT_EMAIL_FROM:-} ALERT_EMAIL_USERNAME: ${ALERT_EMAIL_USERNAME:-} ALERT_EMAIL_PASSWORD: ${ALERT_EMAIL_PASSWORD:-} ALERT_EMAIL_TO: ${ALERT_EMAIL_TO:-} DINGTALK_WEBHOOK_URL: ${DINGTALK_WEBHOOK_URL:-} DINGTALK_AT_MOBILES: ${DINGTALK_AT_MOBILES:-} DINGTALK_KEYWORD: ${DINGTALK_KEYWORD:-告警} WECHAT_WORK_WEBHOOK_URL: ${WECHAT_WORK_WEBHOOK_URL:-} FEISHU_WEBHOOK_URL: ${FEISHU_WEBHOOK_URL:-} SMS_WEBHOOK_URL: ${SMS_WEBHOOK_URL:-} SMS_API_KEY: ${SMS_API_KEY:-} SMS_TEMPLATE_CODE: ${SMS_TEMPLATE_CODE:-} SMS_TO_LIST: ${SMS_TO_LIST:-} ports: - "8080:8080" depends_on: mysql: condition: service_healthy redis: condition: service_healthy minio: condition: service_healthy milvus: condition: service_healthy networks: - agentcraft_default - agentcraft-claw_default healthcheck: test: ["CMD", "curl", "-f", "http://localhost:8080/actuator/health"] interval: 15s timeout: 5s retries: 5 start_period: 60s deploy: resources: limits: cpus: '2' memory: 2G # ===== 前端 ===== frontend: build: context: ./frontend dockerfile: Dockerfile container_name: agentcraft-frontend restart: unless-stopped ports: - "80:80" depends_on: backend: condition: service_healthy networks: - agentcraft-claw_default healthcheck: test: ["CMD", "curl", "-f", "http://localhost/"] interval: 15s timeout: 5s retries: 5 deploy: resources: limits: cpus: '0.5' memory: 256M # ===== 可观测性 ===== loki: image: grafana/loki:2.9.10 container_name: agentcraft-loki restart: unless-stopped networks: - agentcraft_default command: -config.file=/etc/loki/loki-config.yaml volumes: - agentcraft_loki_data:/loki - ./infra/loki/loki-config.yaml:/etc/loki/loki-config.yaml:ro ports: - "3100:3100" deploy: resources: limits: cpus: '0.5' memory: 512M prometheus: image: prom/prometheus:v2.53.0 container_name: agentcraft-prometheus restart: unless-stopped networks: - agentcraft_default command: - '--config.file=/etc/prometheus/prometheus.yml' - '--storage.tsdb.path=/prometheus' - '--storage.tsdb.retention.time=15d' - '--web.console.libraries=/etc/prometheus/console_libraries' - '--web.console.templates=/etc/prometheus/consoles' - '--web.enable-lifecycle' volumes: - ./infra/prometheus/prometheus.yml:/etc/prometheus/prometheus.yml:ro - ./infra/prometheus/alerts.yml:/etc/prometheus/alerts.yml:ro - agentcraft_prometheus_data:/prometheus ports: - "9090:9090" depends_on: backend: condition: service_healthy deploy: resources: limits: cpus: '0.5' memory: 512M grafana: image: grafana/grafana:10.4.4 container_name: agentcraft-grafana restart: unless-stopped networks: - agentcraft_default environment: GF_SECURITY_ADMIN_USER: ${GRAFANA_ADMIN_USER:-admin} GF_SECURITY_ADMIN_PASSWORD: ${GRAFANA_ADMIN_PASSWORD:-admin} GF_USERS_ALLOW_SIGN_UP: "false" volumes: - ./infra/grafana/provisioning:/etc/grafana/provisioning:ro - ./infra/grafana/dashboards:/var/lib/grafana/dashboards:ro - agentcraft_grafana_data:/var/lib/grafana ports: - "3000:3000" depends_on: - prometheus - loki deploy: resources: limits: cpus: '0.5' memory: 256M alertmanager: image: prom/alertmanager:v0.27.0 container_name: agentcraft-alertmanager restart: unless-stopped networks: - agentcraft_default env_file: - .env command: - '--config.file=/etc/alertmanager/alertmanager.yml' - '--storage.path=/alertmanager' - '--web.external-url=http://localhost:9093' - '--cluster.advertise-address=127.0.0.1:9093' volumes: - ./infra/alertmanager/alertmanager.yml:/etc/alertmanager/alertmanager.yml:ro - agentcraft_alertmanager_data:/alertmanager ports: - "9093:9093" depends_on: backend: condition: service_healthy deploy: resources: limits: cpus: '0.5' memory: 256M # ===== Phase 2 基础设施 ===== # RabbitMQ 消息队列 rabbitmq: image: rabbitmq:3.12-management-alpine container_name: agentcraft-rabbitmq restart: unless-stopped networks: - agentcraft_default environment: RABBITMQ_DEFAULT_USER: ${RABBITMQ_USERNAME:-agentcraft} RABBITMQ_DEFAULT_PASS: ${RABBITMQ_PASSWORD:-agentcraft} volumes: - agentcraft_rabbitmq_data:/var/lib/rabbitmq ports: - "5672:5672" - "15672:15672" deploy: resources: limits: cpus: '0.5' memory: 512M # Nacos 配置中心 nacos: image: nacos/nacos-server:v2.3.0 container_name: agentcraft-nacos restart: unless-stopped networks: - agentcraft_default environment: MODE: standalone SPRING_DATASOURCE_PLATFORM: mysql MYSQL_SERVICE_HOST: mysql MYSQL_SERVICE_DB_NAME: nacos MYSQL_SERVICE_PORT: 3306 MYSQL_SERVICE_USER: root MYSQL_SERVICE_PASSWORD: ${MYSQL_ROOT_PASSWORD:-root} NACOS_AUTH_ENABLE: "true" ports: - "8848:8848" - "9848:9848" depends_on: mysql: condition: service_healthy deploy: resources: limits: cpus: '0.5' memory: 1G # Jaeger 链路追踪 jaeger: image: jaegertracing/all-in-one:1.59 container_name: agentcraft-jaeger restart: unless-stopped networks: - agentcraft_default environment: COLLECTOR_OTLP_ENABLED: "true" ports: - "16686:16686" - "4317:4317" - "4318:4318" deploy: resources: limits: cpus: '0.5' memory: 1G # Neo4j 图数据库(Graph RAG) neo4j: image: neo4j:5.20-community container_name: agentcraft-neo4j restart: unless-stopped networks: - agentcraft_default environment: NEO4J_AUTH: ${NEO4J_USERNAME:-neo4j}/${NEO4J_PASSWORD:-agentcraft} NEO4J_PLUGINS: '["apoc", "gds"]' NEO4J_dbms_memory_heap_max__size: 1G volumes: - agentcraft_neo4j_data:/data - agentcraft_neo4j_logs:/logs ports: - "7474:7474" - "7687:7687" deploy: resources: limits: cpus: '1' memory: 2G # Python AI 子服务(Embedding / Rerank / OCR / Safety) python-ai-service: build: context: ./python-ai-service dockerfile: Dockerfile container_name: agentcraft-python-ai restart: unless-stopped networks: - agentcraft_default environment: - APP_PORT=8080 - GRPC_PORT=50051 - MODEL_CACHE_DIR=/models - LOG_LEVEL=INFO volumes: - agentcraft_models_cache:/models ports: - "8081:8080" - "50051:50051" deploy: resources: limits: cpus: '2' memory: 4G # Worker 进程(异步消费者) worker: build: context: ./backend dockerfile: Dockerfile.worker container_name: agentcraft-worker restart: unless-stopped environment: # 数据库 MYSQL_HOST: mysql MYSQL_PORT: 3306 MYSQL_DATABASE: agentcraft MYSQL_USERNAME: root MYSQL_PASSWORD: ${MYSQL_ROOT_PASSWORD:-root} # Redis REDIS_HOST: redis REDIS_PORT: 6379 REDIS_PASSWORD: ${REDIS_PASSWORD:-} # Milvus MILVUS_HOST: milvus MILVUS_PORT: 19530 # RabbitMQ RABBITMQ_HOST: rabbitmq RABBITMQ_PORT: 5672 RABBITMQ_USERNAME: ${RABBITMQ_USERNAME:-agentcraft} RABBITMQ_PASSWORD: ${RABBITMQ_PASSWORD:-agentcraft} # Neo4j NEO4J_URI: ${NEO4J_URI:-bolt://neo4j:7687} NEO4J_USERNAME: ${NEO4J_USERNAME:-neo4j} NEO4J_PASSWORD: ${NEO4J_PASSWORD:-agentcraft} # Python AI gRPC AI_SERVICE_GRPC_HOST: ${AI_SERVICE_GRPC_HOST:-python-ai-service} AI_SERVICE_GRPC_PORT: ${AI_SERVICE_GRPC_PORT:-50051} # 日志 APP_LOG_LEVEL: ${APP_LOG_LEVEL:-INFO} depends_on: mysql: condition: service_healthy redis: condition: service_healthy milvus: condition: service_healthy rabbitmq: condition: service_healthy networks: - agentcraft_default deploy: resources: limits: cpus: '2' memory: 2G # ===== Phase 3: 模型训练与 vLLM 推理 ===== vllm-planner: image: vllm/vllm-openai:v0.5.0 container_name: agentcraft-vllm-planner restart: unless-stopped networks: - agentcraft_default environment: - CUDA_VISIBLE_DEVICES=0 volumes: - agentcraft_models:/models - agentcraft_lora:/lora-adapters command: > --model /models/Qwen2.5-7B --enable-lora --lora-modules planner=/lora-adapters/planner --port 8000 --tensor-parallel-size 1 ports: - "8000:8000" deploy: resources: limits: cpus: '4' memory: 16G # 生产环境启用 GPU 时取消注释: # runtime: nvidia vllm-reviewer: image: vllm/vllm-openai:v0.5.0 container_name: agentcraft-vllm-reviewer restart: unless-stopped networks: - agentcraft_default environment: - CUDA_VISIBLE_DEVICES=0 volumes: - agentcraft_models:/models - agentcraft_lora:/lora-adapters command: > --model /models/Qwen2.5-3B --enable-lora --lora-modules reviewer=/lora-adapters/reviewer,safety=/lora-adapters/safety --port 8001 ports: - "8001:8001" deploy: resources: limits: cpus: '2' memory: 8G # 生产环境启用 GPU 时取消注释: # runtime: nvidia model-training-service: build: context: ./model-training-service dockerfile: Dockerfile container_name: agentcraft-model-trainer restart: unless-stopped networks: - agentcraft_default environment: - VLLM_PLANNER_URL=http://vllm-planner:8000 - VLLM_REVIEWER_URL=http://vllm-reviewer:8001 - MODELS_DIR=/models - LORA_DIR=/lora-adapters volumes: - agentcraft_models:/models - agentcraft_lora:/lora-adapters ports: - "8082:8080" deploy: resources: limits: cpus: '4' memory: 16G # 生产环境启用 GPU 时取消注释: # runtime: nvidia # ===== Phase 4: OPA 策略引擎 ===== opa: image: openpolicyagent/opa:0.65.0 container_name: agentcraft-opa restart: unless-stopped networks: - agentcraft_default command: run --server --addr :8181 /policies volumes: - ./infra/opa/policies:/policies:ro ports: - "8181:8181" healthcheck: test: ["CMD", "wget", "-qO-", "http://localhost:8181/health"] interval: 15s timeout: 5s retries: 5 deploy: resources: limits: cpus: '0.5' memory: 256M volumes: agentcraft_mysql_data: agentcraft_redis_data: agentcraft_etcd_data: agentcraft_minio_data: agentcraft_milvus_data: agentcraft_prometheus_data: agentcraft_grafana_data: agentcraft_loki_data: agentcraft_alertmanager_data: # Phase 2 新增 agentcraft_rabbitmq_data: agentcraft_neo4j_data: agentcraft_neo4j_logs: agentcraft_models_cache: # Phase 3 新增 agentcraft_models: agentcraft_lora: