services:
  # ============================================================================
  # Infrastructure Services
  # ============================================================================

  # PostgreSQL Database
  postgres:
    image: postgres:14
    container_name: astron-agent-postgres
    environment:
      POSTGRES_DB: sparkdb_manager
      POSTGRES_USER: ${POSTGRES_USER:-spark}
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-spark123}
      PGDATA: /var/lib/postgresql/data/pgdata
    volumes:
      - postgres_data:/var/lib/postgresql/data
      - ./pgsql/:/docker-entrypoint-initdb.d/
    networks:
      - astron-agent-network
    restart: always
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER:-spark} -d sparkdb_manager"]
      interval: ${HEALTH_CHECK_INTERVAL:-30s}
      timeout: ${HEALTH_CHECK_TIMEOUT:-10s}
      retries: ${HEALTH_CHECK_RETRIES:-60}

  # MySQL Database
  mysql:
    image: mysql:8.4.6
    container_name: astron-agent-mysql
    environment:
      MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD:-root123}
      MYSQL_DATABASE: ${CONSOLE_MYSQL_DB:-astron_console}
    volumes:
      - mysql_data:/var/lib/mysql
    networks:
      - astron-agent-network
    restart: always
    healthcheck:
      test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
      interval: ${HEALTH_CHECK_INTERVAL:-30s}
      timeout: ${HEALTH_CHECK_TIMEOUT:-10s}
      retries: ${HEALTH_CHECK_RETRIES:-60}

  # Redis Cache
  redis:
    image: redis:7
    container_name: astron-agent-redis
    volumes:
      - redis_data:/data
    networks:
      - astron-agent-network
    restart: always
    command: redis-server ${REDIS_PASSWORD:+--requirepass} ${REDIS_PASSWORD}
    healthcheck:
      test: ["CMD-SHELL", "redis-cli ${REDIS_PASSWORD:+-a \"$REDIS_PASSWORD\"} ping | grep PONG"]
      interval: ${HEALTH_CHECK_INTERVAL:-30s}
      timeout: ${HEALTH_CHECK_TIMEOUT:-10s}
      retries: ${HEALTH_CHECK_RETRIES:-60}

  # Elasticsearch Search Engine
#  elasticsearch:
#    image: elasticsearch:7.16.2
#    container_name: astron-agent-elasticsearch
#    environment:
#      - discovery.type=single-node
#      - "ES_JAVA_OPTS=${ES_JAVA_OPTS:--Xms512m -Xmx512m}"
#      - xpack.security.enabled=${ELASTICSEARCH_SECURITY_ENABLED:-false}
#      - cluster.name=astron-agent-cluster
#    volumes:
#      - elasticsearch_data:/usr/share/elasticsearch/data
#    networks:
#      - astron-agent-network
#    restart: always
#    healthcheck:
#      test: ["CMD", "curl", "-f", "http://localhost:9200/_cluster/health"]
#      interval: ${HEALTH_CHECK_INTERVAL:-30s}
#      timeout: ${HEALTH_CHECK_TIMEOUT:-10s}
#      retries: ${HEALTH_CHECK_RETRIES:-60}

  # Kibana (Elasticsearch Observability)
#  kibana:
#    image: kibana:7.16.2
#    container_name: astron-agent-kibana
#    environment:
#      ELASTICSEARCH_HOSTS: "http://elasticsearch:9200"
#      SERVER_NAME: "astron-agent-kibana"
#    ports:
#      - "${EXPOSE_KIBANA_PORT:-5601}:5601"
#    networks:
#      - astron-agent-network
#    restart: always
#    depends_on:
#      elasticsearch:
#        condition: service_healthy

  # Kafka Message Queue
#  kafka:
#    image: apache/kafka:3.7.0
#    container_name: astron-agent-kafka
#    environment:
#      KAFKA_NODE_ID: 1
#      KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: CONTROLLER:PLAINTEXT,PLAINTEXT:PLAINTEXT
#      KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://kafka:29092
#      KAFKA_LISTENERS: PLAINTEXT://0.0.0.0:29092,CONTROLLER://0.0.0.0:29093
#      KAFKA_INTER_BROKER_LISTENER_NAME: PLAINTEXT
#      KAFKA_CONTROLLER_LISTENER_NAMES: CONTROLLER
#      KAFKA_CONTROLLER_QUORUM_VOTERS: 1@kafka:29093
#      KAFKA_PROCESS_ROLES: broker,controller
#      KAFKA_GROUP_INITIAL_REBALANCE_DELAY_MS: 0
#      KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: ${KAFKA_REPLICATION_FACTOR:-1}
#      KAFKA_TRANSACTION_STATE_LOG_REPLICATION_FACTOR: ${KAFKA_REPLICATION_FACTOR:-1}
#      CLUSTER_ID: ${KAFKA_CLUSTER_ID:-MkU3OEVBNTcwNTJENDM2Qk}
#    volumes:
#      - kafka_data:/var/lib/kafka/data
#    networks:
#      - astron-agent-network
#    restart: always
#    healthcheck:
#      test: ["CMD-SHELL", "netstat -tulpn | grep 29092 || exit 1"]
#      interval: ${HEALTH_CHECK_INTERVAL:-30s}
#      timeout: ${HEALTH_CHECK_TIMEOUT:-10s}
#      retries: ${HEALTH_CHECK_RETRIES:-60}

  # MinIO Object Storage
  minio:
    image: minio/minio:RELEASE.2025-07-23T15-54-02Z
    container_name: astron-agent-minio
    environment:
      MINIO_ROOT_USER: ${MINIO_ROOT_USER:-minioadmin}
      MINIO_ROOT_PASSWORD: ${MINIO_ROOT_PASSWORD:-minioadmin123}
      MINIO_SERVER_URL: ${OSS_REMOTE_ENDPOINT:-http://localhost:18998}
    ports:
      - "${EXPOSE_MINIO_PORT:-9000}:9000"
      - "${EXPOSE_MINIO_CONSOLE_PORT:-9001}:9001"
    volumes:
      - minio_data:/data
    networks:
      - astron-agent-network
    restart: always
    command: server /data --console-address ":9001"
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/live"]
      interval: ${HEALTH_CHECK_INTERVAL:-30s}
      timeout: ${HEALTH_CHECK_TIMEOUT:-10s}
      retries: ${HEALTH_CHECK_RETRIES:-60}

  # Logstash (Kafka -> Elasticsearch)
#  logstash:
#    image: docker.elastic.co/logstash/logstash:7.16.2
#    container_name: astron-agent-logstash
#    environment:
#      LS_JAVA_OPTS: "${LS_JAVA_OPTS:--Xms256m -Xmx256m}"
#    volumes:
#      - ./logstash/pipeline:/usr/share/logstash/pipeline:ro
#    networks:
#      - astron-agent-network
#    restart: always

  # ============================================================================
  # astron-agent Core Services
  # ============================================================================

  # Tenant Service
  core-tenant:
    image: ghcr.io/iflytek/astron-agent/core-tenant:${ASTRON_AGENT_VERSION:-latest}
    container_name: astron-agent-core-tenant
    environment:
      SERVICE_PORT: "${CORE_TENANT_PORT:-5052}"
      SERVICE_LOCATION: "${SERVICE_LOCATION:-hf}"
      DATABASE_DB_TYPE: "${DATABASE_DB_TYPE:-mysql}"
      DATABASE_USERNAME: "${DATABASE_USERNAME:-root}"
      DATABASE_PASSWORD: "${DATABASE_PASSWORD:-root123}"
      DATABASE_URL: "${DATABASE_URL:-(localhost:3306)/tenant}"
      DATABASE_MAX_OPEN_CONNS: "${DATABASE_MAX_OPEN_CONNS:-5}"
      DATABASE_MAX_IDLE_CONNS: "${DATABASE_MAX_IDLE_CONNS:-5}"
      LOG_PATH: "${LOG_PATH:-log.txt}"
    depends_on:
      postgres:
        condition: service_healthy
      mysql:
        condition: service_healthy
      redis:
        condition: service_healthy
      minio:
        condition: service_healthy
    volumes:
      - ./config/tenant/logs:/opt/tenant/logs
      - ./config/tenant/config.toml:/opt/tenant/config/config.toml
      - /etc/localtime:/etc/localtime
    networks:
      - astron-agent-network
    restart: always

  # Memory Database Service

  core-database:
    image: ghcr.io/iflytek/astron-agent/core-database:${ASTRON_AGENT_VERSION:-latest}
    container_name: astron-agent-core-database
    environment:
      SERVICE_PORT: "${CORE_DATABASE_PORT:-7990}"
      DB_TYPE: "${DB_TYPE:-postgresql}"
      PGSQL_HOST: "${POSTGRES_HOST:-postgres}"
      PGSQL_PORT: "${POSTGRES_PORT:-5432}"
      PGSQL_USER: "${POSTGRES_USER:-spark}"
      PGSQL_PASSWORD: "${POSTGRES_PASSWORD:-spark123}"
      PGSQL_DATABASE: "${DATABASE_POSTGRES_DATABASE:-sparkdb_manager}"
      MYSQL_HOST: "${MYSQL_HOST:-mysql}"
      MYSQL_PORT: "${MYSQL_PORT:-3306}"
      MYSQL_USER: "${MYSQL_USER:-root}"
      MYSQL_PASSWORD: "${MYSQL_PASSWORD:-root123}"
      MYSQL_DATABASE: "${DATABASE_MYSQL_DATABASE:-sparkdb_manager}"
      OTLP_ENDPOINT: "${OTLP_ENDPOINT:-127.0.0.1:4317}"
      OTLP_ENABLE: "${OTLP_ENABLE:-0}"
      REDIS_ADDR: "${REDIS_ADDR:-redis:6379}"
      REDIS_CLUSTER_ADDR: "${REDIS_CLUSTER_ADDR}"
      REDIS_PASSWORD: "${REDIS_PASSWORD}"
    depends_on:
      postgres:
        condition: service_healthy
      mysql:
        condition: service_healthy
      redis:
        condition: service_healthy
      minio:
        condition: service_healthy
    volumes:
      - ./config/database/config.env:/opt/core/memory/database/config.env
      - ./config/database/logs/:/opt/core/memory/database/logs
    networks:
      - astron-agent-network
    restart: always

  # RPA Plugin Service
  core-rpa:
    image: ghcr.io/iflytek/astron-agent/core-rpa:${ASTRON_AGENT_VERSION:-latest}
    container_name: astron-agent-core-rpa
    environment:
      SERVICE_PORT: "${CORE_RPA_PORT:-17198}"
      OTLP_ENDPOINT: "${OTLP_ENDPOINT:-127.0.0.1:4317}"
      OTLP_ENABLE: "${OTLP_ENABLE:-0}"
      KAFKA_ENABLE: "${KAFKA_ENABLE:-0}"
      KAFKA_SERVERS: "${KAFKA_SERVERS:-kafka:29092}"
      XIAOWU_RPA_TASK_CREATE_URL: "${XIAOWU_RPA_TASK_CREATE_URL_INTERNAL:-${XIAOWU_RPA_TASK_CREATE_URL}}"
      XIAOWU_RPA_TASK_QUERY_URL: "${XIAOWU_RPA_TASK_QUERY_URL_INTERNAL:-${XIAOWU_RPA_TASK_QUERY_URL}}"
    depends_on:
      postgres:
        condition: service_healthy
      mysql:
        condition: service_healthy
      redis:
        condition: service_healthy
      minio:
        condition: service_healthy
    volumes:
      - ./config/rpa/config.env:/opt/core/plugin/rpa/config.env
      - ./config/rpa/logs/:/opt/core/logs/
    networks:
      - astron-agent-network
    restart: always

  # Link Plugin Service
  core-link:
    image: ghcr.io/iflytek/astron-agent/core-link:${ASTRON_AGENT_VERSION:-latest}
    container_name: astron-agent-core-link
    environment:
      SERVICE_PORT: "${CORE_LINK_PORT:-18888}"
      MYSQL_HOST: "${MYSQL_HOST:-mysql}"
      MYSQL_PORT: "${MYSQL_PORT:-3306}"
      MYSQL_USER: "${MYSQL_USER:-root}"
      MYSQL_PASSWORD: "${MYSQL_PASSWORD:-root123}"
      MYSQL_DB: "${LINK_MYSQL_DB:-spark-link}"
      REDIS_IS_CLUSTER: "${REDIS_IS_CLUSTER:-false}"
      REDIS_ADDR: "${REDIS_ADDR:-redis:6379}"
      REDIS_CLUSTER_ADDR: "${REDIS_CLUSTER_ADDR}"
      REDIS_PASSWORD: "${REDIS_PASSWORD}"
      OTLP_ENDPOINT: "${OTLP_ENDPOINT:-127.0.0.1:4317}"
      OTLP_ENABLE: "${OTLP_ENABLE:-0}"
      KAFKA_ENABLE: "${KAFKA_ENABLE:-0}"
      KAFKA_SERVERS: "${KAFKA_SERVERS:-kafka:29092}"
    depends_on:
      postgres:
        condition: service_healthy
      mysql:
        condition: service_healthy
      redis:
        condition: service_healthy
      minio:
        condition: service_healthy
    volumes:
      - ./config/link/config.env:/opt/core/plugin/link/config.env
      - ./config/link/logs/:/opt/core/plugin/link/logs/
    networks:
      - astron-agent-network
    restart: always

  # AI Tools Plugin Service
  core-aitools:
    image: ghcr.io/iflytek/astron-agent/core-aitools:${ASTRON_AGENT_VERSION:-latest}
    container_name: astron-agent-core-aitools
    environment:
      SERVICE_PORT: "${CORE_AITOOLS_PORT:-18668}"
      OSS_TYPE: "${OSS_TYPE:-s3}"
      OSS_ENDPOINT: "${OSS_ENDPOINT:-http://minio:9000}"
      OSS_ACCESS_KEY_ID: "${OSS_ACCESS_KEY_ID:-minioadmin}"
      OSS_ACCESS_KEY_SECRET: "${OSS_ACCESS_KEY_SECRET:-minioadmin123}"
      OSS_BUCKET_NAME: "${OSS_BUCKET_NAME}"
      OSS_DOWNLOAD_HOST: "${OSS_REMOTE_ENDPOINT}"
      OSS_TTL: "${OSS_TTL:-157788000}"
      KAFKA_ENABLE: "${KAFKA_ENABLE:-0}"
      KAFKA_SERVERS: "${KAFKA_SERVERS:-kafka:29092}"
      REDIS_CLUSTER_ADDR: "${REDIS_CLUSTER_ADDR}"
      REDIS_ADDR: "${REDIS_ADDR:-redis:6379}"
      REDIS_PASSWORD: "${REDIS_PASSWORD}"
      REDIS_DATABASE: "${REDIS_DATABASE:-0}"
      REDIS_DATABASE_CONSOLE: "${REDIS_DATABASE_CONSOLE:-0}"
      MYSQL_HOST: "${MYSQL_HOST:-mysql}"
      MYSQL_PORT: "${MYSQL_PORT:-3306}"
      MYSQL_USER: "${MYSQL_USER:-root}"
      MYSQL_PASSWORD: "${MYSQL_PASSWORD:-root123}"
      CONSOLE_MYSQL_DB: "${CONSOLE_MYSQL_DB:-astron_console}"
      MYSQL_URL: "${MYSQL_URL:-jdbc:mysql://mysql:3306/astron_console?useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=Asia/Shanghai&characterEncoding=utf8&createDatabaseIfNotExist=true}"
    depends_on:
      postgres:
        condition: service_healthy
      mysql:
        condition: service_healthy
      redis:
        condition: service_healthy
      minio:
        condition: service_healthy
    volumes:
      - ./config/aitools/config.env:/opt/core/plugin/aitools/config.env
      - ./config/aitools/logs/:/opt/core/logs/
    networks:
      - astron-agent-network
    restart: always

  # Agent Service
  core-agent:
    image: ghcr.io/iflytek/astron-agent/core-agent:${ASTRON_AGENT_VERSION:-latest}
    container_name: astron-agent-core-agent
    environment:
      SERVICE_LOCATION: "${SERVICE_LOCATION:-hf}"
      SERVICE_HOST: "${SERVICE_HOST:-0.0.0.0}"
      SERVICE_PORT: "${CORE_AGENT_PORT:-17870}"
      SERVICE_WORKERS: "${SERVICE_WORKERS:-1}"
      SERVICE_RELOAD: "${SERVICE_RELOAD:-false}"
      SERVICE_WS_PING_INTERVAL: "${SERVICE_WS_PING_INTERVAL:-false}"
      SERVICE_WS_PING_TIMEOUT: "${SERVICE_WS_PING_TIMEOUT:-false}"
      REDIS_CLUSTER_ADDR: "${REDIS_CLUSTER_ADDR}"
      REDIS_ADDR: "${REDIS_ADDR:-redis:6379}"
      REDIS_PASSWORD: "${REDIS_PASSWORD}"
      REDIS_EXPIRE: "${REDIS_EXPIRE:-3600}"
      MYSQL_HOST: "${MYSQL_HOST:-mysql}"
      MYSQL_PORT: "${MYSQL_PORT:-3306}"
      MYSQL_USER: "${MYSQL_USER:-root}"
      MYSQL_PASSWORD: "${MYSQL_PASSWORD:-root123}"
      MYSQL_DB: "${AGENT_MYSQL_DB:-agent}"
      OTLP_ENDPOINT: "${OTLP_ENDPOINT:-127.0.0.1:4317}"
      OTLP_METRIC_TIMEOUT: "${OTLP_METRIC_TIMEOUT:-3000}"
      OTLP_METRIC_EXPORT_INTERVAL_MILLIS: "${OTLP_METRIC_EXPORT_INTERVAL_MILLIS:-3000}"
      OTLP_METRIC_EXPORT_TIMEOUT_MILLIS: "${OTLP_METRIC_EXPORT_TIMEOUT_MILLIS:-3000}"
      UPLOAD_NODE_TRACE: "${UPLOAD_NODE_TRACE:-true}"
      UPLOAD_METRICS: "${UPLOAD_METRICS:-true}"
      OTLP_TRACE_TIMEOUT: "${OTLP_TRACE_TIMEOUT:-3000}"
      OTLP_TRACE_MAX_QUEUE_SIZE: "${OTLP_TRACE_MAX_QUEUE_SIZE:-2048}"
      OTLP_TRACE_SCHEDULE_DELAY_MILLIS: "${OTLP_TRACE_SCHEDULE_DELAY_MILLIS:-3000}"
      OTLP_TRACE_MAX_EXPORT_BATCH_SIZE: "${OTLP_TRACE_MAX_EXPORT_BATCH_SIZE:-2048}"
      OTLP_TRACE_EXPORT_TIMEOUT_MILLIS: "${OTLP_TRACE_EXPORT_TIMEOUT_MILLIS:-3000}"
      KAFKA_ENABLE: "${KAFKA_ENABLE:-0}"
      KAFKA_SERVERS: "${KAFKA_SERVERS:-kafka:29092}"
      KAFKA_TIMEOUT: "${KAFKA_TIMEOUT:-60}"
      KAFKA_TOPIC: "${AGENT_KAFKA_TOPIC:-spark-agent-builder}"
      GET_LINK_URL: "${GET_LINK_URL:-http://core-link:18888/api/v1/tools}"
      VERSIONS_LINK_URL: "${VERSIONS_LINK_URL:-http://core-link:18888/api/v1/tools/versions}"
      RUN_LINK_URL: "${RUN_LINK_URL:-http://core-link:18888/api/v1/tools/http_run}"
      GET_WORKFLOWS_URL: "${GET_WORKFLOWS_URL:-http://core-workflow:7880/sparkflow/v1/protocol/get}"
      WORKFLOW_SSE_BASE_URL: "${WORKFLOW_SSE_BASE_URL:-http://core-workflow:7880/workflow/v1}"
      CHUNK_QUERY_URL: "${CHUNK_QUERY_URL:-http://core-knowledge:20010/knowledge/v1/chunk/query}"
      LIST_MCP_PLUGIN_URL: "${LIST_MCP_PLUGIN_URL:-http://core-link:18888/api/v1/mcp/tool_list}"
      RUN_MCP_PLUGIN_URL: "${RUN_MCP_PLUGIN_URL:-http://core-link:18888/api/v1/mcp/call_tool}"
      APP_AUTH_HOST: "${APP_AUTH_HOST:-core-tenant}"
      APP_AUTH_PROT: "${APP_AUTH_PROT:-http}"
      APP_AUTH_API_KEY: "${APP_AUTH_API_KEY:-YOUR_APP_AUTH_API_KEY}"
      APP_AUTH_SECRET: "${APP_AUTH_SECRET:-YOUR_APP_AUTH_SECRET}"
    depends_on:
      postgres:
        condition: service_healthy
      mysql:
        condition: service_healthy
      redis:
        condition: service_healthy
      minio:
        condition: service_healthy
    volumes:
      - ./config/agent/config.env:/opt/core/agent/config.env
    networks:
      - astron-agent-network
    healthcheck:
      test: ["CMD-SHELL", "python -c \"import os, urllib.request; urllib.request.urlopen('http://localhost:%s/health/ready' % os.getenv('SERVICE_PORT', '17870'), timeout=5).read()\""]
      interval: ${HEALTH_CHECK_INTERVAL:-30s}
      timeout: ${HEALTH_CHECK_TIMEOUT:-10s}
      retries: ${HEALTH_CHECK_RETRIES:-60}
    restart: always

  # Knowledge Base Service
  core-knowledge:
    image: ghcr.io/iflytek/astron-agent/core-knowledge:${ASTRON_AGENT_VERSION:-latest}
    container_name: astron-agent-core-knowledge
    # Map container's localhost to host machine, to access services on the host
    extra_hosts:
      - "localhost:host-gateway"
    environment:
      SERVICE_PORT: "${CORE_KNOWLEDGE_PORT:-20010}"
      OTLP_ENABLE: "${OTLP_ENABLE:-0}"
    depends_on:
      postgres:
        condition: service_healthy
      mysql:
        condition: service_healthy
      redis:
        condition: service_healthy
      minio:
        condition: service_healthy
    volumes:
      - ./config/knowledge/config.env:/opt/core/knowledge/config.env
      - ./config/knowledge/logs/:/opt/core/logs
    networks:
      - astron-agent-network
    healthcheck:
      test: ["CMD-SHELL", "python -c \"import os, urllib.request; urllib.request.urlopen('http://localhost:%s/health/ready' % os.getenv('SERVICE_PORT', '20010'), timeout=5).read()\""]
      interval: ${HEALTH_CHECK_INTERVAL:-30s}
      timeout: ${HEALTH_CHECK_TIMEOUT:-10s}
      retries: ${HEALTH_CHECK_RETRIES:-60}
    restart: always

  # Workflow Service
  core-workflow:
    image: ghcr.io/iflytek/astron-agent/core-workflow:${ASTRON_AGENT_VERSION:-latest}
    container_name: astron-agent-core-workflow
    environment:
      RUNTIME_ENV: "${RUNTIME_ENV:-dev}"
      SERVICE_PORT: "${CORE_WORKFLOW_PORT:-7880}"
      MYSQL_HOST: "${MYSQL_HOST:-mysql}"
      MYSQL_PORT: "${MYSQL_PORT:-3306}"
      MYSQL_USER: "${MYSQL_USER:-root}"
      MYSQL_PASSWORD: "${MYSQL_PASSWORD:-root123}"
      MYSQL_DB: "${WORKFLOW_MYSQL_DB:-workflow}"
      REDIS_CLUSTER_ADDR: "${REDIS_CLUSTER_ADDR}"
      REDIS_ADDR: "${REDIS_ADDR:-redis:6379}"
      REDIS_PASSWORD: "${REDIS_PASSWORD}"
      REDIS_EXPIRE: "${REDIS_EXPIRE:-3600}"
      OTLP_ENDPOINT: "${OTLP_ENDPOINT:-127.0.0.1:4317}"
      OTLP_ENABLE: "${OTLP_ENABLE:-0}"
      OTLP_METRIC_EXPORT_INTERVAL_MILLIS: "${OTLP_METRIC_EXPORT_INTERVAL_MILLIS:-3000}"
      OTLP_METRIC_EXPORT_TIMEOUT_MILLIS: "${OTLP_METRIC_EXPORT_TIMEOUT_MILLIS:-3000}"
      OTLP_METRIC_TIMEOUT: "${OTLP_METRIC_TIMEOUT:-3000}"
      OTLP_TRACE_TIMEOUT: "${OTLP_TRACE_TIMEOUT:-3000}"
      OTLP_TRACE_MAX_QUEUE_SIZE: "${OTLP_TRACE_MAX_QUEUE_SIZE:-2048}"
      OTLP_TRACE_SCHEDULE_DELAY_MILLIS: "${OTLP_TRACE_SCHEDULE_DELAY_MILLIS:-3000}"
      OTLP_TRACE_MAX_EXPORT_BATCH_SIZE: "${OTLP_TRACE_MAX_EXPORT_BATCH_SIZE:-500}"
      OTLP_TRACE_EXPORT_TIMEOUT_MILLIS: "${OTLP_TRACE_EXPORT_TIMEOUT_MILLIS:-3000}"
      OSS_TYPE: "${OSS_TYPE:-s3}"
      OSS_ENDPOINT: "${OSS_ENDPOINT:-http://minio:9000}"
      OSS_ACCESS_KEY_ID: "${OSS_ACCESS_KEY_ID:-minioadmin}"
      OSS_ACCESS_KEY_SECRET: "${OSS_ACCESS_KEY_SECRET:-minioadmin123}"
      OSS_BUCKET_NAME: "${OSS_BUCKET_NAME}"
      OSS_DOWNLOAD_HOST: "${OSS_REMOTE_ENDPOINT}"
      OSS_TTL: "${OSS_TTL:-157788000}"
      KAFKA_ENABLE: "${KAFKA_ENABLE:-0}"
      KAFKA_SERVERS: "${KAFKA_SERVERS:-kafka:29092}"
      KAFKA_TIMEOUT: "${KAFKA_TIMEOUT:-60}"
      KAFKA_TOPIC: "${WORKFLOW_KAFKA_TOPIC:-spark-agent-builder}"
      KNOWLEDGE_BASE_URL: "${KNOWLEDGE_BASE_URL:-http://core-knowledge:${CORE_KNOWLEDGE_PORT}}"
      KNOWLEDGE_PRO_BASE_URL: "${KNOWLEDGE_PRO_BASE_URL:-http://core-knowledge:${CORE_KNOWLEDGE_PORT}}"
      PLUGIN_BASE_URL: "${PLUGIN_BASE_URL:-http://core-link:${CORE_LINK_PORT}}"
      WORKFLOW_BASE_URL: "${WORKFLOW_BASE_URL:-http://core-workflow:${CORE_WORKFLOW_PORT}}"
      APP_MANAGE_PLAT_BASE_URL: "${APP_MANAGE_PLAT_BASE_URL:-http://core-tenant:${CORE_TENANT_PORT}}"
      AGENT_BASE_URL: "${AGENT_BASE_URL:-http://core-agent:${CORE_AGENT_PORT}}"
      PGSQL_BASE_URL: "${PGSQL_BASE_URL:-http://core-database:${CORE_DATABASE_PORT}}"
      RPA_BASE_URL: "${RPA_BASE_URL:-http://core-rpa:${CORE_RPA_PORT}}"
    depends_on:
      postgres:
        condition: service_healthy
      mysql:
        condition: service_healthy
      redis:
        condition: service_healthy
      minio:
        condition: service_healthy
    volumes:
      - ./config/workflow/config.env:/opt/core/workflow/config.env
      - ./config/workflow/logs/:/opt/core/logs
    networks:
      - astron-agent-network
    healthcheck:
      test: ["CMD-SHELL", "python -c \"import os, urllib.request; urllib.request.urlopen('http://localhost:%s/health/ready' % os.getenv('SERVICE_PORT', '7880'), timeout=5).read()\""]
      interval: ${HEALTH_CHECK_INTERVAL:-30s}
      timeout: ${HEALTH_CHECK_TIMEOUT:-10s}
      retries: ${HEALTH_CHECK_RETRIES:-60}
    restart: always

  # ============================================================================
  # astron-agent Console Services
  # ============================================================================

  # Nginx Reverse Proxy
  nginx:
    image: nginx:1.25-alpine
    container_name: astron-agent-nginx
    ulimits:
      nofile:
        soft: 65535
        hard: 65535
    ports:
      - "${EXPOSE_NGINX_PORT:-80}:80"
    volumes:
      - ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro
      - nginx_logs:/var/log/nginx
    depends_on:
      - console-frontend
      - console-hub
    networks:
      - astron-agent-network
    restart: always
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost/nginx-health"]
      interval: ${HEALTH_CHECK_INTERVAL:-30s}
      timeout: ${HEALTH_CHECK_TIMEOUT:-10s}
      retries: ${HEALTH_CHECK_RETRIES:-60}

  # Console Frontend
  console-frontend:
    image: ghcr.io/iflytek/astron-agent/console-frontend:${ASTRON_AGENT_VERSION:-latest}
    container_name: astron-agent-console-frontend
    environment:
      CONSOLE_CASDOOR_URL: "${CONSOLE_CASDOOR_URL:-}"
      CONSOLE_CASDOOR_ID: "${CONSOLE_CASDOOR_ID:-}"
      CONSOLE_CASDOOR_APP: "${CONSOLE_CASDOOR_APP:-}"
      CONSOLE_CASDOOR_ORG: "${CONSOLE_CASDOOR_ORG:-}"
    expose:
      - "1881"
    networks:
      - astron-agent-network
    restart: always

#   Console Hub Service
  console-hub:
    image: ghcr.io/iflytek/astron-agent/console-hub:${ASTRON_AGENT_VERSION:-latest}
    container_name: astron-agent-console-hub
    # Map container's localhost to host machine, to access MinIO and other services from both inside and outside the container
    extra_hosts:
      - "localhost:host-gateway"
    environment:
      CONSOLE_CASDOOR_URL: "${CONSOLE_CASDOOR_URL:-}"
      CONSOLE_CASDOOR_ID: "${CONSOLE_CASDOOR_ID:-}"
      CONSOLE_CASDOOR_APP: "${CONSOLE_CASDOOR_APP:-}"
      CONSOLE_CASDOOR_ORG: "${CONSOLE_CASDOOR_ORG:-}"
      CONSOLE_DOMAIN: "${CONSOLE_DOMAIN:-https://your.deployment.domain}"
      MYSQL_URL: "${MYSQL_URL:-jdbc:mysql://mysql:3306/astron_console?useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=Asia/Shanghai&characterEncoding=utf8&createDatabaseIfNotExist=true}"
      MYSQL_USER: "${MYSQL_USER:-root}"
      MYSQL_PASSWORD: "${MYSQL_PASSWORD:-root123}"
      REDIS_HOST: "${REDIS_HOST:-redis}"
      REDIS_PORT: "${REDIS_PORT:-6379}"
      REDIS_PASSWORD: "${REDIS_PASSWORD}"
      REDIS_DATABASE_CONSOLE: "${REDIS_DATABASE_CONSOLE:-0}"
      OSS_ENDPOINT: "${OSS_ENDPOINT:-http://minio:9000}"
      OSS_REMOTE_ENDPOINT: "${OSS_REMOTE_ENDPOINT:-http://minio:9000}"
      OSS_ACCESS_KEY_ID: "${OSS_ACCESS_KEY_ID:-minioadmin}"
      OSS_ACCESS_KEY_SECRET: "${OSS_ACCESS_KEY_SECRET:-minioadmin123}"
      OSS_BUCKET_CONSOLE: "${OSS_BUCKET_CONSOLE:-console}"
      OSS_PRESIGN_EXPIRY_SECONDS_CONSOLE: "${OSS_PRESIGN_EXPIRY_SECONDS_CONSOLE:-600}"
      OAUTH2_ISSUER_URI: "${OAUTH2_ISSUER_URI:-http://auth-server:8000}"
      OAUTH2_JWK_SET_URI: "${OAUTH2_JWK_SET_URI:-http://auth-server:8000/.well-known/jwks}"
      OAUTH2_AUDIENCE: "${OAUTH2_AUDIENCE:-your-oauth2-client-id}"
      WECHAT_COMPONENT_APPID: "${WECHAT_COMPONENT_APPID:-your-wechat-component-appid}"
      WECHAT_COMPONENT_SECRET: "${WECHAT_COMPONENT_SECRET:-your-wechat-component-secret}"
      WECHAT_TOKEN: "${WECHAT_TOKEN:-your-wechat-token}"
      WECHAT_ENCODING_AES_KEY: "${WECHAT_ENCODING_AES_KEY:-your-wechat-encoding-aes-key}"
      WORKFLOW_CHAT_URL: "${WORKFLOW_CHAT_URL:-http://core-workflow:7880/workflow/v1/chat/completions}"
      WORKFLOW_DEBUG_URL: "${WORKFLOW_DEBUG_URL:-http://core-workflow:7880/workflow/v1/debug/chat/completions}"
      WORKFLOW_RESUME_URL: "${WORKFLOW_RESUME_URL:-http://core-workflow:7880/workflow/v1/resume}"
      COMMON_APPID: "${COMMON_APPID:-appid}"
      COMMON_APIKEY: "${COMMON_APIKEY:-apiKey}"
      COMMON_API_SECRET: "${COMMON_API_SECRET:-apiSecret}"
      TENANT_ID: "${TENANT_ID:-tenantId}"
      TENANT_KEY: "${TENANT_KEY:-tenantKey}"
      TENANT_SECRET: "${TENANT_SECRET:-tenantSecret}"
      ADMIN_UID: "${ADMIN_UID:-9999}"
      APP_URL: "${APP_URL:-}"
      KNOWLEDGE_URL: "${KNOWLEDGE_URL:-}"
      TOOL_URL: "${TOOL_URL:-}"
      TOOL_RPA_URL: "${TOOL_RPA_URL:-}"
      WORKFLOW_URL: "${WORKFLOW_URL:-}"
      SPARK_DB_URL: "${SPARK_DB_URL:-}"
      SPARK_DB_TYPE: "${SPARK_DB_TYPE:-postgresql}"
      LOCAL_MODEL_URL: "${LOCAL_MODEL_URL:-}"
      RPA_URL: "${RPA_URL_INTERNAL:-${RPA_URL}}"
      MAAS_APP_ID: "${MAAS_APP_ID:-your-maas-app-id}"
      MAAS_API_KEY: "${MAAS_API_KEY:-your-maas-api-key}"
      MAAS_API_SECRET: "${MAAS_API_SECRET:-your-maas-api-secret}"
      MAAS_CONSUMER_ID: "${MAAS_CONSUMER_ID:-your-maas-consumer-id}"
      MAAS_CONSUMER_SECRET: "${MAAS_CONSUMER_SECRET:-your-maas-consumer-secret}"
      MAAS_CONSUMER_KEY: "${MAAS_CONSUMER_KEY:-your-maas-consumer-key}"
      MAAS_WORKFLOW_VERSION: "${MAAS_WORKFLOW_VERSION:-}"
      MAAS_SYNCHRONIZE_WORK_FLOW: "${MAAS_SYNCHRONIZE_WORK_FLOW:-}"
      MAAS_PUBLISH: "${MAAS_PUBLISH:-}"
      MAAS_CLONE_WORK_FLOW: "${MAAS_CLONE_WORK_FLOW:-}"
      MAAS_GET_INPUTS: "${MAAS_GET_INPUTS:-}"
      MAAS_CAN_PUBLISH_URL: "${MAAS_CAN_PUBLISH_URL:-}"
      MAAS_PUBLISH_API: "${MAAS_PUBLISH_API:-}"
      MAAS_AUTH_API: "${MAAS_AUTH_API:-}"
      MAAS_MCP_REGISTER: "${MAAS_MCP_REGISTER:-}"
      MAAS_WORKFLOW_CONFIG: "${MAAS_WORKFLOW_CONFIG:-}"
      BOT_API_CBM_BASE_URL: "${BOT_API_CBM_BASE_URL:-}"
      BOT_API_MAAS_BASE_URL: "${BOT_API_MAAS_BASE_URL:-}"
      TENANT_CREATE_APP: "${TENANT_CREATE_APP:-}"
      TENANT_GET_APP_DETAIL: "${TENANT_GET_APP_DETAIL:-}"
      TENANT_VERIFY_APP_AUTH: "${TENANT_VERIFY_APP_AUTH:-http://core-tenant:${CORE_TENANT_PORT:-5052}/v2/app/key/verify}"
      
    expose:
      - "8080"
    depends_on:
      postgres:
        condition: service_healthy
      mysql:
        condition: service_healthy
      redis:
        condition: service_healthy
      minio:
        condition: service_healthy
    networks:
      - astron-agent-network
    restart: always

# ============================================================================
# Network Configuration
# ============================================================================
networks:
  astron-agent-network:
    driver: bridge

# ============================================================================
# Volume Configuration
# ============================================================================
volumes:
  postgres_data:
    driver: local
  mysql_data:
    driver: local
  redis_data:
    driver: local
  elasticsearch_data:
    driver: local
  kafka_data:
    driver: local
  minio_data:
    driver: local
  nginx_logs:
    driver: local
