services:
  router:
    build:
      context: ./services/router
      dockerfile: Dockerfile
    container_name: dagi-staging-router
    environment:
    - ROUTER_CONFIG_PATH=/app/router_config.yaml
    - LOG_LEVEL=info
    - NODE_ID=node-1-hetzner-gex44
    - MEMORY_SERVICE_URL=http://memory-service:8000
    - QDRANT_HOST=qdrant
    - QDRANT_PORT=6333
    - QDRANT_ENABLED=true
    - NEO4J_BOLT_URL=bolt://neo4j:7687
    - NEO4J_HTTP_URL=http://neo4j:7474
    - NEO4J_USER=neo4j
    - NEO4J_PASSWORD=DaarionNeo4j2026!
    - DEEPSEEK_API_KEY=sk-0db94e8193ec4a6e9acd593ee8d898e7
    - MISTRAL_API_KEY=40Gwjo8nVBx4i4vIkgszvXw9bOwDOu4G
    - COHERE_API_KEY=nOdOXnuepLku2ipJWpe6acWgAsJCsDhMO0RnaEJB
    - GROK_API_KEY=xai-69zEnDse8qRuQyZATs9jVKgfwdyvkHzgEVrTbV0OTAurZqsjHmvGepXG6H9GhVRYEC7E4NFl6iZeG0ww
    - VISION_ENCODER_URL=http://vision-encoder:8001
    - SWAPPER_SERVICE_URL=http://swapper-service:8890
    - IMAGE_GEN_URL=http://swapper-service:8890/image/generate
    - STT_SERVICE_URL=http://swapper-service:8890
    - STT_SERVICE_UPLOAD_URL=http://swapper-service:8890/stt
    - OCR_SERVICE_URL=http://swapper-service:8890
    - WEB_SEARCH_SERVICE_URL=http://swapper-service:8890
    - JWT_SECRET=${JWT_SECRET}
    - SERVICE_AUD=microdao-internal
    - SERVICE_ISS=microdao
    - SERVICE_ID=router
    - SERVICE_ROLE=router
    - NATS_URL=nats://dagi-staging-nats:4222
    volumes:
    - ./services/router/router_config.yaml:/app/router_config.yaml:ro
    - ./logs:/app/logs
    networks:
    - dagi-staging-network
    restart: unless-stopped
    healthcheck:
      test:
      - CMD-SHELL
      - python -c "import urllib.request; urllib.request.urlopen('http://localhost:8000/health')"
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 10s
    env_file:
    - ./.env.staging
    labels:
      com.daarion.env: staging
  swapper-service:
    build:
      context: ./services/swapper-service
      dockerfile: Dockerfile
    container_name: dagi-staging-swapper-service
    environment:
    - OLLAMA_BASE_URL=http://172.18.0.1:11434
    - SWAPPER_CONFIG_PATH=/app/config/swapper_config.yaml
    - SWAPPER_MODE=single-active
    - MAX_CONCURRENT_MODELS=2
    - MODEL_SWAP_TIMEOUT=300
    - GPU_ENABLED=true
    - NODE_ID=node-1-hetzner-gex44
    - HF_HOME=/root/.cache/huggingface
    - CUDA_VISIBLE_DEVICES=0
    - CRAWL4AI_URL=http://crawl4ai:11235
    - GROK_API_KEY=xai-69zEnDse8qRuQyZATs9jVKgfwdyvkHzgEVrTbV0OTAurZqsjHmvGepXG6H9GhVRYEC7E4NFl6iZeG0ww
    - MISTRAL_API_KEY=40Gwjo8nVBx4i4vIkgszvXw9bOwDOu4G
    volumes:
    - ./services/swapper-service/config/swapper_config_node1.yaml:/app/config/swapper_config.yaml:ro
    - ./logs:/app/logs
    - swapper-hf-cache-staging:/root/.cache/huggingface
    deploy:
      resources:
        reservations:
          devices:
          - driver: nvidia
            count: 1
            capabilities:
            - gpu
    networks:
    - dagi-staging-network
    restart: unless-stopped
    extra_hosts:
    - host.docker.internal:172.18.0.1
    healthcheck:
      test:
      - CMD-SHELL
      - wget -qO- http://localhost:8890/health || exit 1
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 60s
    env_file:
    - ./.env.staging
    labels:
      com.daarion.env: staging
  crawl4ai:
    image: unclecode/crawl4ai:latest
    container_name: dagi-staging-crawl4ai
    environment:
    - CRAWL4AI_API_TOKEN=${CRAWL4AI_API_TOKEN:-}
    - MAX_CONCURRENT_TASKS=5
    networks:
    - dagi-staging-network
    restart: unless-stopped
    healthcheck:
      test:
      - CMD
      - curl
      - -f
      - http://localhost:11235/health
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 30s
    env_file:
    - ./.env.staging
    labels:
      com.daarion.env: staging
  gateway:
    build:
      context: ./gateway-bot
      dockerfile: Dockerfile
    container_name: dagi-staging-gateway
    environment:
    - ROUTER_URL=http://router:8000
    - HELION_TELEGRAM_BOT_TOKEN=8112062582:AAGS-HwRLEI269lDutLtAJTFArsIq31YNhE
    - HELION_NAME=Helion
    - HELION_PROMPT_PATH=/app/gateway-bot/helion_prompt.txt
    - GREENFOOD_TELEGRAM_BOT_TOKEN=7495165343:AAHz62qPdP2WAsVHpupPbkGAmpL94sEnNtw
    - DRUID_TELEGRAM_BOT_TOKEN=8145618489:AAHquXktVRkcuU-kN4QxWf6yeJ5TDl_C7wg
    - TELEGRAM_BOT_TOKEN=8323412397:AAFUhRiQpEbyoeX36FgvdIPJl1_8PdJsmkE
    - GREENFOOD_NAME=GREENFOOD
    - GREENFOOD_PROMPT_PATH=/app/gateway-bot/greenfood_prompt.txt
    - NUTRA_TELEGRAM_BOT_TOKEN=8517315428:AAGTLcKxBAZDsMgx28agKTvl1SqJGi0utH4
    - NUTRA_NAME=NUTRA
    - NUTRA_PROMPT_PATH=/app/gateway-bot/nutra_prompt.txt
    - DRUID_PROMPT_PATH=/app/gateway-bot/prompts/druid_prompt.txt
    - MEMORY_SERVICE_URL=http://memory-service:8000
    - SWAPPER_SERVICE_URL=http://swapper-service:8890
    - IMAGE_GEN_URL=http://swapper-service:8890/image/generate
    - STT_SERVICE_URL=http://swapper-service:8890
    - STT_SERVICE_UPLOAD_URL=http://swapper-service:8890/stt
    - OCR_SERVICE_URL=http://swapper-service:8890
    - WEB_SEARCH_SERVICE_URL=http://swapper-service:8890
    - JWT_SECRET=${JWT_SECRET}
    - SERVICE_AUD=microdao-internal
    - SERVICE_ISS=microdao
    - SERVICE_ID=gateway
    - SERVICE_ROLE=gateway
    volumes:
    - ./gateway-bot:/app/gateway-bot:ro
    - ./logs:/app/logs
    depends_on:
    - router
    - memory-service
    networks:
    - dagi-staging-network
    restart: unless-stopped
    healthcheck:
      test:
      - CMD-SHELL
      - python -c "import urllib.request; urllib.request.urlopen('http://localhost:9300/health')"
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 10s
    env_file:
    - ./.env.staging
    labels:
      com.daarion.env: staging
  memory-service:
    build:
      context: ./services/memory-service
      dockerfile: Dockerfile
    container_name: dagi-staging-memory-service
    environment:
    - MEMORY_POSTGRES_HOST=dagi-postgres
    - MEMORY_POSTGRES_PORT=5432
    - MEMORY_POSTGRES_USER=daarion
    - MEMORY_POSTGRES_PASSWORD=DaarionDB2026!
    - MEMORY_POSTGRES_DB=daarion_main
    - MEMORY_QDRANT_HOST=dagi-qdrant-node1
    - MEMORY_QDRANT_PORT=6333
    - MEMORY_COHERE_API_KEY=nOdOXnuepLku2ipJWpe6acWgAsJCsDhMO0RnaEJB
    - MEMORY_DEBUG=false
    - JWT_SECRET=${JWT_SECRET}
    - SERVICE_AUD=microdao-internal
    - SERVICE_ISS=microdao
    - SERVICE_ID=memory
    - SERVICE_ROLE=memory
    - NEO4J_BOLT_URL=bolt://dagi-neo4j-node1:7687
    volumes:
    - ./logs:/app/logs
    depends_on:
    - qdrant
    networks:
    - dagi-staging-network
    restart: unless-stopped
    healthcheck:
      test:
      - CMD-SHELL
      - python -c "import urllib.request; urllib.request.urlopen('http://localhost:8000/health')"
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 10s
    expose:
    - '8000'
    env_file:
    - ./.env.staging
    labels:
      com.daarion.env: staging
  qdrant:
    image: qdrant/qdrant:v1.7.4
    container_name: dagi-staging-qdrant
    ulimits:
      nofile:
        soft: 65535
        hard: 65535
    volumes:
    - qdrant-data-staging:/qdrant/storage
    networks:
      dagi-staging-network:
        aliases:
        - qdrant
        - dagi-qdrant-node1
    restart: unless-stopped
    environment: []
    env_file:
    - ./.env.staging
    labels:
      com.daarion.env: staging
  neo4j:
    image: neo4j:5.15-community
    container_name: dagi-staging-neo4j
    environment:
    - NEO4J_AUTH=neo4j/DaarionNeo4j2026!
    - NEO4J_PLUGINS=["apoc"]
    - NEO4J_dbms_memory_heap_initial__size=512m
    - NEO4J_dbms_memory_heap_max__size=2G
    volumes:
    - neo4j-data-staging:/data
    - neo4j-logs-staging:/logs
    networks:
      dagi-staging-network:
        aliases:
        - neo4j
        - dagi-neo4j-node1
    restart: unless-stopped
    healthcheck:
      test:
      - CMD
      - wget
      - --no-verbose
      - --tries=1
      - --spider
      - http://localhost:7474
      interval: 30s
      timeout: 10s
      retries: 3
    env_file:
    - ./.env.staging
    labels:
      com.daarion.env: staging
  redis:
    image: redis:7-alpine
    container_name: dagi-staging-redis
    volumes:
    - redis-data-staging:/data
    networks:
      dagi-staging-network:
        aliases:
        - redis
        - dagi-redis-node1
    restart: unless-stopped
    healthcheck:
      test:
      - CMD
      - redis-cli
      - PING
      interval: 30s
      timeout: 5s
      retries: 3
    environment: []
    env_file:
    - ./.env.staging
    labels:
      com.daarion.env: staging
  vision-encoder:
    build:
      context: ./services/vision-encoder
      dockerfile: Dockerfile
    container_name: dagi-staging-vision-encoder
    environment:
    - DEVICE=cpu
    - 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-staging:/root/.cache/clip
    depends_on:
    - qdrant
    networks:
    - dagi-staging-network
    restart: unless-stopped
    healthcheck:
      test:
      - CMD-SHELL
      - python -c "import urllib.request; urllib.request.urlopen('http://localhost:8001/health')"
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 60s
    env_file:
    - ./.env.staging
    labels:
      com.daarion.env: staging
  crewai-service:
    build:
      context: ./services/crewai-service
      dockerfile: Dockerfile
    container_name: dagi-staging-crewai-service
    environment:
    - ROUTER_URL=http://router:8000
    - DEEPSEEK_API_KEY=${DEEPSEEK_API_KEY}
    - MISTRAL_API_KEY=${MISTRAL_API_KEY}
    - JWT_SECRET=${JWT_SECRET}
    - SERVICE_AUD=microdao-internal
    - SERVICE_ISS=microdao
    - SERVICE_ID=worker
    - SERVICE_ROLE=worker
    networks:
    - dagi-staging-network
    depends_on:
    - router
    restart: unless-stopped
    env_file:
    - ./.env.staging
    labels:
      com.daarion.env: staging
  crewai-worker:
    build:
      context: ./services/crewai-worker
      dockerfile: Dockerfile
    container_name: dagi-staging-crewai-worker
    environment:
    - ROUTER_URL=http://router:9102
    - JWT_SECRET=${JWT_SECRET}
    - SERVICE_AUD=microdao-internal
    - SERVICE_ISS=microdao
    - SERVICE_ID=worker
    - SERVICE_ROLE=worker
    - NATS_URL=nats://dagi-staging-nats:4222
    networks:
    - dagi-staging-network
    depends_on:
    - router
    env_file:
    - ./.env.staging
    labels:
      com.daarion.env: staging
  dagi-postgres:
    image: postgres:15-alpine
    container_name: dagi-staging-postgres
    environment:
      POSTGRES_DB: daarion_main
      POSTGRES_USER: daarion
      POSTGRES_PASSWORD: DaarionDB2026!
    volumes:
    - postgres-data-staging:/var/lib/postgresql/data
    networks:
      dagi-staging-network:
        aliases:
        - dagi-postgres
        - postgres
    labels:
      com.daarion.env: staging
    env_file:
    - ./.env.staging
  nats:
    image: nats:latest
    container_name: dagi-staging-nats
    command:
    - -c
    - /etc/nats/nats.conf
    volumes:
    - nats-data-staging:/data
    - ./nats/nats.staging.conf:/etc/nats/nats.conf:ro
    networks:
    - dagi-staging-network
    labels:
      com.daarion.env: staging
    env_file:
    - ./.env.staging
  control-plane:
    image: control-plane:latest
    container_name: dagi-staging-control-plane
    environment:
      JWT_SECRET: ${JWT_SECRET}
      SERVICE_ID: control-plane
      SERVICE_ROLE: controlplane
      SERVICE_AUD: microdao-internal
      SERVICE_ISS: microdao
    networks:
    - dagi-staging-network
    labels:
      com.daarion.env: staging
    env_file:
    - ./.env.staging
volumes:
  qdrant-data-staging: null
  neo4j-data-staging: null
  neo4j-logs-staging: null
  redis-data-staging: null
  postgres-data-staging: null
  nats-data-staging: null
  vision-model-cache-staging: null
  swapper-hf-cache-staging: null
networks:
  dagi-staging-network: null
