# =============================================================================
# docker-compose.prod.services.yml — Production Backend & Frontend Services
# =============================================================================
# Contains: All NestJS microservices, Nginx reverse proxy, Next.js frontend
# Requires: docker-compose.prod.databases.yml running first (claw-network must exist)
# Uses production Dockerfiles (not Dockerfile.dev), no source volume mounts.
#
# All services read environment variables from the root .env file.
# Copy .env.example to .env before running.
#
# Usage:
#   docker compose -f docker-compose.prod.services.yml up -d
#   ../scripts/claw.sh --prod services:up
# =============================================================================

name: claw

services:
  # ---------------------------------------------------------------------------
  # Microservices
  # ---------------------------------------------------------------------------
  auth-service:
    build:
      context: ..
      dockerfile: apps/claw-auth-service/Dockerfile
    container_name: claw-auth-service
    restart: unless-stopped
    env_file: ../.env
    environment:
      SEED_ON_START: 'true'
    ports:
      - '4001:4001'
    volumes:
      - ../certs:/certs:ro
    healthcheck:
      test:
        [
          'CMD-SHELL',
          'wget --no-check-certificate -qO- https://localhost:4001/api/v1/health || exit 1',
        ]
      interval: 15s
      timeout: 10s
      retries: 5
      start_period: 30s
    networks:
      - claw-network

  chat-service:
    build:
      context: ..
      dockerfile: apps/claw-chat-service/Dockerfile
    container_name: claw-chat-service
    restart: unless-stopped
    env_file: ../.env
    ports:
      - '4002:4002'
    volumes:
      - ../certs:/certs:ro
    healthcheck:
      test:
        [
          'CMD-SHELL',
          'wget --no-check-certificate -qO- https://localhost:4002/api/v1/health || exit 1',
        ]
      interval: 15s
      timeout: 10s
      retries: 5
      start_period: 30s
    networks:
      - claw-network

  connector-service:
    build:
      context: ..
      dockerfile: apps/claw-connector-service/Dockerfile
    container_name: claw-connector-service
    restart: unless-stopped
    env_file: ../.env
    ports:
      - '4003:4003'
    volumes:
      - ../certs:/certs:ro
    healthcheck:
      test:
        [
          'CMD-SHELL',
          'wget --no-check-certificate -qO- https://localhost:4003/api/v1/health || exit 1',
        ]
      interval: 15s
      timeout: 10s
      retries: 5
      start_period: 30s
    networks:
      - claw-network

  routing-service:
    build:
      context: ..
      dockerfile: apps/claw-routing-service/Dockerfile
    container_name: claw-routing-service
    restart: unless-stopped
    env_file: ../.env
    ports:
      - '4004:4004'
    volumes:
      - ../certs:/certs:ro
    healthcheck:
      test:
        [
          'CMD-SHELL',
          'wget --no-check-certificate -qO- https://localhost:4004/api/v1/health || exit 1',
        ]
      interval: 15s
      timeout: 10s
      retries: 5
      start_period: 30s
    networks:
      - claw-network

  memory-service:
    build:
      context: ..
      dockerfile: apps/claw-memory-service/Dockerfile
    container_name: claw-memory-service
    restart: unless-stopped
    env_file: ../.env
    ports:
      - '4005:4005'
    volumes:
      - ../certs:/certs:ro
    healthcheck:
      test:
        [
          'CMD-SHELL',
          'wget --no-check-certificate -qO- https://localhost:4005/api/v1/health || exit 1',
        ]
      interval: 15s
      timeout: 10s
      retries: 5
      start_period: 30s
    networks:
      - claw-network

  file-service:
    build:
      context: ..
      dockerfile: apps/claw-file-service/Dockerfile
    container_name: claw-file-service
    restart: unless-stopped
    env_file: ../.env
    # Slice D foundation 3 — OCR pipeline. env_file already loads everything
    # from root .env; this explicit passthrough block is a documentation hint
    # so future maintainers see OCR is a file-service concern. Values are
    # interpolated from the root .env at compose-up time.
    environment:
      OCR_ENABLED: ${OCR_ENABLED:-false}
    ports:
      - '4006:4006'
    volumes:
      - file-storage-data:/data/files
      - ../certs:/certs:ro
    # Slice C foundation 3 — ZIP archive expansion uses an in-memory tmpfs so
    # ZIP-bomb extraction can never fill the host disk and so temp files
    # disappear if the container crashes mid-extraction. Cap matches the
    # ZIP_MAX_EXTRACTED_SIZE_MB default × 2 for headroom.
    tmpfs:
      - /tmp/claw-zip-extraction:size=1g,mode=1700
    healthcheck:
      test:
        [
          'CMD-SHELL',
          'wget --no-check-certificate -qO- https://localhost:4006/api/v1/health || exit 1',
        ]
      interval: 15s
      timeout: 10s
      retries: 5
      start_period: 30s
    networks:
      - claw-network

  audit-service:
    build:
      context: ..
      dockerfile: apps/claw-audit-service/Dockerfile
    container_name: claw-audit-service
    restart: unless-stopped
    env_file: ../.env
    ports:
      - '4007:4007'
    volumes:
      - ../certs:/certs:ro
    healthcheck:
      test:
        [
          'CMD-SHELL',
          'wget --no-check-certificate -qO- https://localhost:4007/api/v1/health || exit 1',
        ]
      interval: 15s
      timeout: 10s
      retries: 5
      start_period: 30s
    networks:
      - claw-network

  ollama-service:
    build:
      context: ..
      dockerfile: apps/claw-ollama-service/Dockerfile
    container_name: claw-ollama-service
    restart: unless-stopped
    env_file: ../.env
    ports:
      - '4008:4008'
    volumes:
      - ../certs:/certs:ro
      # Shared with claw-comfyui — the ComfyUI runtime adapter writes
      # HuggingFace-downloaded weights into this volume so ComfyUI can pick
      # them up on the next /object_info refresh. Mount is read-write because
      # the adapter creates files; ComfyUI itself never writes here at runtime.
      - comfyui-models-data:/var/lib/claw/comfyui-models
    healthcheck:
      test:
        [
          'CMD-SHELL',
          'wget --no-check-certificate -qO- https://localhost:4008/api/v1/health || exit 1',
        ]
      interval: 15s
      timeout: 10s
      retries: 5
      start_period: 30s
    networks:
      - claw-network

  client-logs-service:
    build:
      context: ..
      dockerfile: apps/claw-client-logs-service/Dockerfile
    container_name: claw-client-logs-service
    restart: unless-stopped
    env_file: ../.env
    ports:
      - '4010:4010'
    volumes:
      - ../certs:/certs:ro
    healthcheck:
      test:
        [
          'CMD-SHELL',
          'wget --no-check-certificate -qO- https://localhost:4010/api/v1/health || exit 1',
        ]
      interval: 15s
      timeout: 10s
      retries: 5
      start_period: 30s
    networks:
      - claw-network

  server-logs-service:
    build:
      context: ..
      dockerfile: apps/claw-server-logs-service/Dockerfile
    container_name: claw-server-logs-service
    restart: unless-stopped
    env_file: ../.env
    ports:
      - '4011:4011'
    volumes:
      - ../certs:/certs:ro
    healthcheck:
      test:
        [
          'CMD-SHELL',
          'wget --no-check-certificate -qO- https://localhost:4011/api/v1/health || exit 1',
        ]
      interval: 15s
      timeout: 10s
      retries: 5
      start_period: 30s
    networks:
      - claw-network

  health-service:
    build:
      context: ..
      dockerfile: apps/claw-health-service/Dockerfile
    container_name: claw-health-service
    restart: unless-stopped
    env_file: ../.env
    ports:
      - '4009:4009'
    volumes:
      - ../certs:/certs:ro
    healthcheck:
      test:
        [
          'CMD-SHELL',
          'wget --no-check-certificate -qO- https://localhost:4009/api/v1/health || exit 1',
        ]
      interval: 15s
      timeout: 10s
      retries: 5
      start_period: 30s
    networks:
      - claw-network

  # ---------------------------------------------------------------------------
  # Nginx Reverse Proxy
  # ---------------------------------------------------------------------------
  nginx:
    image: nginx:alpine
    container_name: claw-nginx
    restart: unless-stopped
    ports:
      - '4000:80'
      - '443:443'
    volumes:
      - ../infra/nginx/nginx.conf:/etc/nginx/nginx.conf:ro
      - ../certs:/etc/nginx/certs:ro
    depends_on:
      auth-service:
        condition: service_healthy
      chat-service:
        condition: service_healthy
      connector-service:
        condition: service_healthy
      routing-service:
        condition: service_healthy
      memory-service:
        condition: service_healthy
      file-service:
        condition: service_healthy
      audit-service:
        condition: service_healthy
      ollama-service:
        condition: service_healthy
      client-logs-service:
        condition: service_healthy
      server-logs-service:
        condition: service_healthy
      health-service:
        condition: service_healthy
    networks:
      - claw-network

  # ---------------------------------------------------------------------------
  # Image Service
  # ---------------------------------------------------------------------------
  image-service:
    build:
      context: ..
      dockerfile: apps/claw-image-service/Dockerfile
    container_name: claw-image-service
    restart: unless-stopped
    env_file: ../.env
    ports:
      - '4012:4012'
    volumes:
      - ../certs:/certs:ro
    healthcheck:
      test:
        [
          'CMD-SHELL',
          'wget --no-check-certificate -qO- https://localhost:4012/api/v1/health || exit 1',
        ]
      interval: 15s
      timeout: 10s
      retries: 10
      start_period: 45s
    networks:
      - claw-network

  # ---------------------------------------------------------------------------
  # Workspace Service
  # ---------------------------------------------------------------------------
  workspace-service:
    build:
      context: ..
      dockerfile: apps/claw-workspace-service/Dockerfile
    container_name: claw-workspace-service
    restart: unless-stopped
    env_file: ../.env
    ports:
      - '4014:4014'
    volumes:
      - ../certs:/certs:ro
    healthcheck:
      test:
        [
          'CMD-SHELL',
          'wget --no-check-certificate -qO- https://localhost:4014/api/v1/health || exit 1',
        ]
      interval: 15s
      timeout: 10s
      retries: 10
      start_period: 45s
    networks:
      - claw-network

  # ---------------------------------------------------------------------------
  # Agent Service
  # ---------------------------------------------------------------------------
  agent-service:
    build:
      context: ..
      dockerfile: apps/claw-agent-service/Dockerfile
    container_name: claw-agent-service
    restart: unless-stopped
    env_file: ../.env
    ports:
      - '4015:4015'
    volumes:
      - ../certs:/certs:ro
    healthcheck:
      test:
        [
          'CMD-SHELL',
          'wget --no-check-certificate -qO- https://localhost:4015/api/v1/health || exit 1',
        ]
      interval: 15s
      timeout: 10s
      retries: 10
      start_period: 45s
    networks:
      - claw-network

  # ---------------------------------------------------------------------------
  # Research Service
  # ---------------------------------------------------------------------------
  research-service:
    build:
      context: ..
      dockerfile: apps/claw-research-service/Dockerfile
    container_name: claw-research-service
    restart: unless-stopped
    env_file: ../.env
    ports:
      - '4016:4016'
    volumes:
      - ../certs:/certs:ro
    healthcheck:
      test:
        [
          'CMD-SHELL',
          'wget --no-check-certificate -qO- https://localhost:4016/api/v1/health || exit 1',
        ]
      interval: 15s
      timeout: 10s
      retries: 10
      start_period: 45s
    networks:
      - claw-network

  # ---------------------------------------------------------------------------
  # Llamacpp Service (Local Frontier — Phase 1+)
  # ---------------------------------------------------------------------------
  llamacpp-service:
    build:
      context: ..
      dockerfile: apps/claw-llamacpp-service/Dockerfile
    container_name: claw-llamacpp-service
    restart: unless-stopped
    env_file: ../.env
    ports:
      - '4017:4017'
    volumes:
      - llamacpp-data:/var/lib/claw/llamacpp
      - ../certs:/certs:ro
    healthcheck:
      # llamacpp-service runs on node:26-bookworm-slim which ships curl
      # but not wget. -k skips TLS verify so the self-signed cert passes.
      test: ['CMD-SHELL', 'curl -kfs https://localhost:4017/api/v1/health || exit 1']
      interval: 15s
      timeout: 10s
      retries: 10
      start_period: 60s
    networks:
      - claw-network

  # ---------------------------------------------------------------------------
  # File Generation Service
  # ---------------------------------------------------------------------------
  file-generation-service:
    build:
      context: ..
      dockerfile: apps/claw-file-generation-service/Dockerfile
    container_name: claw-file-generation-service
    restart: unless-stopped
    env_file: ../.env
    ports:
      - '4013:4013'
    volumes:
      - ../certs:/certs:ro
    healthcheck:
      test:
        [
          'CMD-SHELL',
          'wget --no-check-certificate -qO- https://localhost:4013/api/v1/health || exit 1',
        ]
      interval: 15s
      timeout: 10s
      retries: 10
      start_period: 45s
    networks:
      - claw-network

  # Frontend
  # ---------------------------------------------------------------------------
  frontend:
    build:
      context: ../apps/claw-frontend
      dockerfile: Dockerfile
      args:
        NEXT_PUBLIC_API_URL: ${NEXT_PUBLIC_API_URL:-}
    container_name: claw-frontend
    restart: unless-stopped
    env_file: ../.env
    ports:
      - '${FRONTEND_PORT:-3000}:3000'
    depends_on:
      - nginx
    volumes:
      - ../certs:/certs:ro
    healthcheck:
      test: ['CMD-SHELL', 'wget -qO- http://localhost:3000 || exit 1']
      interval: 15s
      timeout: 10s
      retries: 5
      start_period: 20s
    networks:
      - claw-network

volumes:
  file-storage-data:
    driver: local
  llamacpp-data:
    driver: local
  # Shared with claw-comfyui (defined in docker-compose.prod.ollama.yml).
  # Declared here as a normal named volume rather than `external: true`
  # because docker-compose merges multi-file volume definitions — both
  # files must agree on the shape. `external: true` requires the volume
  # to already exist when *any* compose file is processed, which fails
  # on fresh installs before comfyui has run once.
  comfyui-models-data:
    driver: local

networks:
  claw-network:
    external: true
    name: claw-network
