services:
  # DAGI Router Node-2 - Core routing service for Node-2
  router:
    build:
      context: .
      dockerfile: Dockerfile
    container_name: dagi-router-node2
    ports:
      - "9102:9102"
    environment:
      - DAGI_ROUTER_CONFIG=/app/router-config.yml
      - RBAC_BASE_URL=http://rbac:9200
      - DEVTOOLS_BASE_URL=http://devtools:8008
      - CREWAI_BASE_URL=http://crewai:9010
      - RAG_SERVICE_URL=http://rag-service:9500
      - MEMORY_SERVICE_URL=http://memory-service:8000
    volumes:
      - ./router-config.yml:/app/router-config.yml:ro
      - ./logs:/app/logs
    depends_on:
      - devtools
      - crewai
      - rbac
    labels:
      - "node=node-2"
      - "service=dagi-router"
    networks:
      - dagi-network
    restart: unless-stopped
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:9102/health"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 10s

  # DevTools Backend
  devtools:
    build:
      context: ./devtools-backend
      dockerfile: Dockerfile
    container_name: dagi-devtools
    ports:
      - "8008:8008"
    volumes:
      - ./workspace:/workspace
      - ./logs:/app/logs
    networks:
      - dagi-network
    restart: unless-stopped
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:8008/health"]
      interval: 30s
      timeout: 10s
      retries: 3

  # CrewAI Orchestrator
  crewai:
    build:
      context: ./orchestrator
      dockerfile: Dockerfile
    container_name: dagi-crewai
    ports:
      - "9010:9010"
    environment:
      - ROUTER_URL=http://router:9102
    volumes:
      - ./logs:/app/logs
    networks:
      - dagi-network
    restart: unless-stopped
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:9010/health"]
      interval: 30s
      timeout: 10s
      retries: 3

  # Bot Gateway (with DAARWIZZ)
  gateway:
    build:
      context: ./gateway-bot
      dockerfile: Dockerfile
    container_name: dagi-gateway
    ports:
      - "9300:9300"
    environment:
      - ROUTER_URL=http://router:9102
      - TELEGRAM_BOT_TOKEN=${TELEGRAM_BOT_TOKEN:-}
      - DISCORD_BOT_TOKEN=${DISCORD_BOT_TOKEN:-}
      - DAARWIZZ_TELEGRAM_BOT_TOKEN=${DAARWIZZ_TELEGRAM_BOT_TOKEN:-}
      - DAARWIZZ_NAME=${DAARWIZZ_NAME:-DAARWIZZ}
      - DAARWIZZ_PROMPT_PATH=/app/gateway-bot/daarwizz_prompt.txt
      - HELION_TELEGRAM_BOT_TOKEN=${HELION_TELEGRAM_BOT_TOKEN:-}
      - HELION_NAME=${HELION_NAME:-Helion}
      - HELION_PROMPT_PATH=/app/gateway-bot/helion_prompt.txt
      - MEMORY_SERVICE_URL=http://memory-service:8000
    volumes:
      - ./logs:/app/logs
    depends_on:
      - router
    networks:
      - dagi-network
    restart: unless-stopped
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:9300/health"]
      interval: 30s
      timeout: 10s
      retries: 3

  # microDAO RBAC Service
  rbac:
    build:
      context: ./microdao
      dockerfile: Dockerfile
    container_name: dagi-rbac
    ports:
      - "9200:9200"
    environment:
      - DATABASE_URL=${RBAC_DATABASE_URL:-sqlite:///rbac.db}
    volumes:
      - ./data/rbac:/app/data
      - ./logs:/app/logs
    networks:
      - dagi-network
    restart: unless-stopped
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:9200/health"]
      interval: 30s
      timeout: 10s
      retries: 3

  # RAG Service
  rag-service:
    build:
      context: ./services/rag-service
      dockerfile: Dockerfile
    container_name: dagi-rag-service
    ports:
      - "9500:9500"
    environment:
      - PG_DSN=${PG_DSN:-postgresql+psycopg2://postgres:postgres@city-db:5432/daarion_city}
      - EMBED_MODEL_NAME=${EMBED_MODEL_NAME:-BAAI/bge-m3}
      - EMBED_DEVICE=${EMBED_DEVICE:-cpu}
      - ROUTER_BASE_URL=http://router:9102
    volumes:
      - ./logs:/app/logs
      - rag-model-cache:/root/.cache/huggingface
    depends_on:
      - router
    networks:
      - dagi-network
    restart: unless-stopped
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:9500/health"]
      interval: 30s
      timeout: 10s
      retries: 3

  # PostgreSQL Database (Production: external volume)
  postgres:
    image: postgres:15-alpine
    container_name: dagi-postgres
    ports:
      - "5432:5432"
    environment:
      - POSTGRES_USER=postgres
      - POSTGRES_PASSWORD=postgres
      - POSTGRES_DB=daarion
    volumes:
      - microdao-daarion_postgres_data:/var/lib/postgresql/data
      - ./services/memory-service/init.sql:/docker-entrypoint-initdb.d/init.sql
    networks:
      - dagi-network
    restart: unless-stopped
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U postgres"]
      interval: 10s
      timeout: 5s
      retries: 5

  # Memory Service
  memory-service:
    build:
      context: ./services/memory-service
      dockerfile: Dockerfile
    container_name: dagi-memory-service
    ports:
      - "8000:8000"
    environment:
      - DATABASE_URL=${MEMORY_DATABASE_URL:-postgresql://postgres:postgres@postgres:5432/daarion_memory}
      - LOG_LEVEL=${LOG_LEVEL:-INFO}
    volumes:
      - ./logs:/app/logs
      - memory-data:/app/data
    depends_on:
      - postgres
    networks:
      - dagi-network
    restart: unless-stopped
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:8000/health"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 10s

  # Vision Encoder Service - OpenCLIP for text/image embeddings
  vision-encoder:
    build:
      context: ./services/vision-encoder
      dockerfile: Dockerfile
    container_name: dagi-vision-encoder
    ports:
      - "8001:8001"
    environment:
      - DEVICE=${VISION_DEVICE:-cuda}
      - MODEL_NAME=${VISION_MODEL_NAME:-ViT-L-14}
      - MODEL_PRETRAINED=${VISION_MODEL_PRETRAINED:-openai}
      - NORMALIZE_EMBEDDINGS=true
      - QDRANT_HOST=qdrant
      - QDRANT_PORT=6333
      - QDRANT_ENABLED=true
    volumes:
      - ./logs:/app/logs
      - vision-model-cache:/root/.cache/clip
    depends_on:
      - qdrant
    networks:
      - dagi-network
    restart: unless-stopped
    # GPU support - requires nvidia-container-toolkit
    deploy:
      resources:
        reservations:
          devices:
            - driver: nvidia
              count: 1
              capabilities: [gpu]
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:8001/health"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 60s

  # Qdrant Vector Database - for image/text embeddings
  qdrant:
    image: qdrant/qdrant:v1.7.4
    container_name: dagi-qdrant
    ports:
      - "6333:6333"  # HTTP API
      - "6334:6334"  # gRPC API
    volumes:
      - qdrant-data:/qdrant/storage
    networks:
      - dagi-network
    restart: unless-stopped
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:6333/healthz"]
      interval: 30s
      timeout: 10s
      retries: 3

  # Node Registry Service - Central registry for DAGI network nodes
  node-registry:
    build:
      context: ./services/node-registry
      dockerfile: Dockerfile
    container_name: dagi-node-registry
    ports:
      - "9205:9205"  # Internal network only
    environment:
      - NODE_REGISTRY_DB_HOST=postgres
      - NODE_REGISTRY_DB_PORT=5432
      - NODE_REGISTRY_DB_NAME=node_registry
      - NODE_REGISTRY_DB_USER=node_registry_user
      - NODE_REGISTRY_DB_PASSWORD=${NODE_REGISTRY_DB_PASSWORD:-CHANGE_ME_STRONG_PASSWORD}
      - NODE_REGISTRY_HTTP_PORT=9205
      - NODE_REGISTRY_ENV=production
      - NODE_REGISTRY_LOG_LEVEL=info
    volumes:
      - ./logs:/app/logs
    depends_on:
      - postgres
    networks:
      - dagi-network
    restart: unless-stopped
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:9205/health"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 10s

  # Swapper Service - Dynamic model loading service (Node #2)
  swapper-service:
    build:
      context: ./services/swapper-service
      dockerfile: Dockerfile
    container_name: swapper-service
    ports:
      - "8890:8890"
    extra_hosts:
      - "host.docker.internal:host-gateway"  # MacBook Docker Desktop compatibility
    environment:
      - OLLAMA_BASE_URL=http://host.docker.internal:11434  # Access host Ollama from Docker
      - SWAPPER_CONFIG_PATH=/app/config/swapper_config.yaml
      - SWAPPER_MODE=single-active
      - MAX_CONCURRENT_MODELS=1
      - MODEL_SWAP_TIMEOUT=30
    volumes:
      - ./services/swapper-service/config:/app/config:ro
      - ./logs:/app/logs
    networks:
      - dagi-network
    restart: unless-stopped
    healthcheck:
      test: ["CMD-SHELL", "wget -qO- http://localhost:8890/health || exit 1"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 10s

  # Agent Cabinet Service
  agent-cabinet:
    build:
      context: ./services/agent-cabinet-service
      dockerfile: Dockerfile
    container_name: dagi-agent-cabinet
    ports:
      - "8898:8898"
    environment:
      - ROUTER_URL=http://router:9102
    networks:
      - dagi-network
    restart: unless-stopped
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:8898/health"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 10s

  # City Service - MicroDAO Core Logic
  city-service:
    build:
      context: ./services/city-service
      dockerfile: Dockerfile
    container_name: daarion-city-service
    ports:
      - "7001:7001"
    environment:
      - DATABASE_URL=postgresql://postgres:postgres@dagi-postgres:5432/daarion
      - MATRIX_GATEWAY_URL=http://gateway:9300
      - NATS_URL=nats://dagi-nats:4222
      - LOG_LEVEL=INFO
    volumes:
      - ./logs:/app/logs
      - ./services/city-service/static:/app/static
    depends_on:
      - postgres
      - gateway
    networks:
      - dagi-network
    restart: unless-stopped
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:7001/health"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 10s

volumes:
  rag-model-cache:
    driver: local
  memory-data:
    driver: local
  # Production: use existing external volume with all DAARION data
  microdao-daarion_postgres_data:
    external: true
  vision-model-cache:
    driver: local
  qdrant-data:
    driver: local

networks:
  dagi-network:
    driver: bridge
    name: dagi-network
