# ─────────────────────────────────────────────────
# Idswyft Community Edition — Self-Hosted Install
# ─────────────────────────────────────────────────
# Quick start (pulls pre-built images, ~2 minutes):
#   ./install.sh        (interactive setup)
#   docker compose up -d
#   Visit http://localhost
#
# Build from source instead:
#   docker compose -f docker-compose.yml -f docker-compose.build.yml up -d --build
#
# Enable HTTPS (optional — run install.sh with HTTPS setup first):
#   docker compose --profile https up -d
# ─────────────────────────────────────────────────

services:
  # ─────────────────────────────────────────
  # PostgreSQL database
  # ─────────────────────────────────────────
  postgres:
    image: postgres:16-alpine
    restart: unless-stopped
    # Resource limits prevent any single container from taking down the host
    # under load (e.g. malicious upload triggering OOM in the engine
    # cascading into the database via cgroup pressure). Per the audit,
    # tuned for the recommended deployment spec (4 vCPU / 8GB RAM).
    mem_limit: 1g
    labels:
      - "com.centurylinklabs.watchtower.enable=false"
    volumes:
      - pgdata:/var/lib/postgresql/data
    environment:
      POSTGRES_DB: ${DB_NAME:-idswyft}
      POSTGRES_USER: ${DB_USER:-idswyft}
      POSTGRES_PASSWORD: ${DB_PASSWORD:-changeme-in-production}
    healthcheck:
      test: ["CMD-SHELL", "PGPASSWORD=${DB_PASSWORD:-changeme-in-production} psql -U ${DB_USER:-idswyft} -d ${DB_NAME:-idswyft} -c 'SELECT 1' >/dev/null 2>&1"]
      interval: 5s
      timeout: 5s
      retries: 5

  # ─────────────────────────────────────────
  # ML verification engine (OCR, face detection, liveness)
  # ─────────────────────────────────────────
  engine:
    image: ghcr.io/team-idswyft/idswyft-engine:latest
    restart: unless-stopped
    # Engine spikes to ~1.5GB during ML inference (PaddleOCR + face-api +
    # ONNX + Sharp). 2g cap leaves headroom for concurrent extractions
    # without the unbounded growth that would OOM the host. cpus: 2.0
    # because OCR + face detection both parallelize well on multiple cores.
    mem_limit: 2g
    cpus: 2.0
    labels:
      - "com.centurylinklabs.watchtower.enable=true"
    environment:
      NODE_ENV: production
      PORT: "3002"
      LOG_LEVEL: info
    healthcheck:
      test: ["CMD", "wget", "-qO-", "http://localhost:3002/health"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 60s

  # ─────────────────────────────────────────
  # Core identity verification API
  # ─────────────────────────────────────────
  api:
    image: ghcr.io/team-idswyft/idswyft-api:latest
    restart: unless-stopped
    # API is request-routing + light orchestration — 1g is plenty.
    # cpus: 1.0 since the heavy work (OCR, face match) is offloaded to engine.
    mem_limit: 1g
    cpus: 1.0
    labels:
      - "com.centurylinklabs.watchtower.enable=true"
    depends_on:
      postgres:
        condition: service_healthy
      engine:
        condition: service_healthy
    environment:
      NODE_ENV: production
      PORT: "3001"
      DATABASE_URL: postgresql://${DB_USER:-idswyft}:${DB_PASSWORD:-changeme-in-production}@postgres:5432/${DB_NAME:-idswyft}
      JWT_SECRET: ${JWT_SECRET:-change-this-jwt-secret}
      API_KEY_SECRET: ${API_KEY_SECRET:-change-this-api-key-secret}
      ENCRYPTION_KEY: ${ENCRYPTION_KEY:-change-this-32-char-encrypt-key!}
      SERVICE_TOKEN: ${SERVICE_TOKEN:-change-this-service-token}
      CORS_ORIGINS: "${CORS_ORIGINS:-}"
      STORAGE_PROVIDER: "${STORAGE_PROVIDER:-local}"
      AWS_ACCESS_KEY_ID: "${AWS_ACCESS_KEY_ID:-}"
      AWS_SECRET_ACCESS_KEY: "${AWS_SECRET_ACCESS_KEY:-}"
      AWS_REGION: "${AWS_REGION:-us-east-1}"
      AWS_S3_BUCKET: "${AWS_S3_BUCKET:-}"
      DATABASE_SSL: "${DATABASE_SSL:-}"
      DATABASE_SSL_REJECT_UNAUTHORIZED: "${DATABASE_SSL_REJECT_UNAUTHORIZED:-}"
      RATE_LIMIT_ENABLED: "${RATE_LIMIT_ENABLED:-true}"
      SANDBOX_MODE: ${SANDBOX_MODE:-false}
      MIGRATIONS_LENIENT: "true"
      ENGINE_URL: http://engine:3002
      WATCHTOWER_API_TOKEN: "${WATCHTOWER_API_TOKEN:-}"
    volumes:
      - uploads:/app/backend/uploads
      - temp:/app/backend/temp
      - ./supabase/migrations:/app/backend/migrations:ro
    healthcheck:
      test: ["CMD", "wget", "-qO-", "http://localhost:3001/health"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 40s

  # ─────────────────────────────────────────
  # Dev Portal frontend (community edition)
  # ─────────────────────────────────────────
  frontend:
    image: ghcr.io/team-idswyft/idswyft-frontend:latest
    restart: unless-stopped
    # nginx serving static React build — minimal RAM/CPU.
    mem_limit: 256m
    cpus: 0.5
    labels:
      - "com.centurylinklabs.watchtower.enable=true"
    depends_on:
      - api
    ports:
      - "${IDSWYFT_PORT:-80}:8080"

  # ─────────────────────────────────────────
  # Caddy reverse proxy (optional HTTPS)
  # Only starts with: docker compose --profile https up -d
  # IMPORTANT: Set IDSWYFT_PORT=127.0.0.1:8080 in .env to avoid port 80 conflict
  # ─────────────────────────────────────────
  caddy:
    image: caddy:2-alpine
    restart: unless-stopped
    # Caddy as reverse proxy / TLS terminator — minimal footprint.
    mem_limit: 256m
    cpus: 0.5
    profiles:
      - https
    depends_on:
      - frontend
    ports:
      - "80:80"
      - "443:443"
      - "443:443/udp"
    environment:
      DOMAIN: ${DOMAIN:-localhost}
    volumes:
      - ./caddy/Caddyfile:/etc/caddy/Caddyfile:ro
      - ./caddy/certs:/etc/caddy/certs:ro
      - caddy_data:/data
      - caddy_config:/config
    healthcheck:
      test: ["CMD", "wget", "-qO", "/dev/null", "--no-check-certificate", "https://localhost/"]
      interval: 30s
      timeout: 5s
      retries: 3
      start_period: 30s

  # ─────────────────────────────────────────
  # Watchtower (optional auto-update sidecar)
  # Only starts with: docker compose --profile autoupdate up -d
  # ─────────────────────────────────────────
  watchtower:
    image: containrrr/watchtower
    restart: unless-stopped
    profiles:
      - autoupdate
    environment:
      WATCHTOWER_LABEL_ENABLE: "true"
      WATCHTOWER_SCHEDULE: "${WATCHTOWER_SCHEDULE:-0 0 4 * * *}"
      WATCHTOWER_CLEANUP: "true"
      WATCHTOWER_ROLLING_RESTART: "true"
      WATCHTOWER_HTTP_API_METRICS: "true"
      WATCHTOWER_HTTP_API_TOKEN: "${WATCHTOWER_API_TOKEN:-}"
      TZ: "${TZ:-UTC}"
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro
    labels:
      - "com.centurylinklabs.watchtower.enable=false"

volumes:
  pgdata:
  uploads:
  temp:
  caddy_data:
  caddy_config:
