name: manuagent services: postgres: image: postgres:17-alpine restart: unless-stopped environment: POSTGRES_DB: ${POSTGRES_DB:-smart_factory_agent} POSTGRES_USER: ${POSTGRES_USER:-smart_factory} POSTGRES_PASSWORD_FILE: /run/secrets/postgres_password secrets: - postgres_password volumes: - postgres-data:/var/lib/postgresql/data networks: - manuagent-network healthcheck: test: ["CMD-SHELL", "pg_isready -U $${POSTGRES_USER} -d $${POSTGRES_DB}"] interval: 5s timeout: 5s retries: 20 start_period: 10s # 此服务负责构建并登记 AgentScope 使用的 Runtime 镜像。 # 它成功退出后,后端会通过 Docker Socket 按 Session 动态创建真正执行任务的 Runtime 容器。 agent-runtime: image: ${AGENT_RUNTIME_IMAGE:-smart-factory-agent-runtime:0.1.0} build: context: ./sandbox dockerfile: Dockerfile command: ["/bin/true"] restart: "no" networks: - manuagent-network backend: image: ${BACKEND_IMAGE:-manuagent-backend:0.1.0} build: context: ./server dockerfile: Dockerfile restart: unless-stopped init: true depends_on: postgres: condition: service_healthy restart: true agent-runtime: condition: service_completed_successfully environment: SPRING_DATASOURCE_URL: jdbc:postgresql://postgres:5432/${POSTGRES_DB:-smart_factory_agent} SPRING_DATASOURCE_USERNAME: ${POSTGRES_USER:-smart_factory} # Spring Boot 将 secrets 目录中的点分文件名作为配置属性加载,避免把密码写进普通环境变量。 SPRING_CONFIG_IMPORT: optional:configtree:/run/secrets/ APP_DATA_ROOT: ${MANUAGENT_DATA_ROOT:-/srv/manuagent/data} APP_DASHSCOPE_KEY_FILE: /run/secrets/dashscope_key APP_ADMIN_USERNAME: ${APP_ADMIN_USERNAME:-admin} APP_SANDBOX_IMAGE: ${AGENT_RUNTIME_IMAGE:-smart-factory-agent-runtime:0.1.0} APP_SANDBOX_NETWORK: manuagent-network APP_RUN_TIMEOUT: ${APP_RUN_TIMEOUT:-60m} SERVER_SERVLET_SESSION_COOKIE_SECURE: ${SESSION_COOKIE_SECURE:-false} secrets: - source: postgres_password target: spring.datasource.password - source: app_master_key target: app.master-key - source: admin_password target: app.admin-password - source: dashscope_api_key target: dashscope_key volumes: # DockerSandbox 的 bind mount 源路径由宿主机 daemon 解释,因此容器内外必须使用相同绝对路径。 - type: bind source: ${MANUAGENT_DATA_ROOT:-/srv/manuagent/data} target: ${MANUAGENT_DATA_ROOT:-/srv/manuagent/data} # AgentScope 需要通过宿主机 Docker Engine 创建、执行并销毁隔离的 Runtime 容器。 - type: bind source: /var/run/docker.sock target: /var/run/docker.sock expose: - "8080" networks: - manuagent-network healthcheck: test: ["CMD", "curl", "--fail", "--silent", "--show-error", "http://127.0.0.1:8080/api/auth/csrf"] interval: 10s timeout: 5s retries: 18 start_period: 30s stop_grace_period: 30s frontend: image: ${FRONTEND_IMAGE:-manuagent-frontend:0.1.0} build: context: ./web-ui dockerfile: Dockerfile restart: unless-stopped init: true depends_on: backend: condition: service_healthy restart: true ports: # 默认严格监听 0.0.0.0:5173;仅当宿主机保留该端口时,才通过 FRONTEND_PORT 临时覆盖。 - "0.0.0.0:${FRONTEND_PORT:-5173}:80" networks: - manuagent-network healthcheck: test: ["CMD", "wget", "--quiet", "--output-document=/dev/null", "http://127.0.0.1/"] interval: 10s timeout: 5s retries: 6 start_period: 10s networks: manuagent-network: # 固定网络名,确保后端动态创建的 Agent Runtime 容器可以加入同一个网络。 name: manuagent-network driver: bridge volumes: postgres-data: secrets: postgres_password: environment: POSTGRES_PASSWORD app_master_key: environment: APP_MASTER_KEY admin_password: environment: APP_ADMIN_PASSWORD dashscope_api_key: environment: DASHSCOPE_API_KEY