# Production Docker Compose for TipSharks
# Usage: docker compose -f docker-compose.prod.yml up -d
#
# Prerequisites:
#   1. Copy .env.prod.example to .env.prod and fill in secrets
#   2. Place SSL certificates in ./infrastructure/nginx/ssl/
#   3. docker compose -f docker-compose.prod.yml --env-file .env.prod up -d

version: "3.8"

services:
  # ==========================================================================
  # Databases
  # ==========================================================================

  postgres-ingest:
    image: postgres:16-alpine
    container_name: tipsharks-postgres-ingest
    restart: always
    environment:
      POSTGRES_DB: racing_db
      POSTGRES_USER: ${POSTGRES_INGEST_USER}
      POSTGRES_PASSWORD: ${POSTGRES_INGEST_PASSWORD}
    volumes:
      - pg-ingest-data:/var/lib/postgresql/data
    networks:
      - tipsharks-network
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_INGEST_USER} -d racing_db"]
      interval: 10s
      timeout: 5s
      retries: 5
    deploy:
      resources:
        limits:
          memory: 1G

  postgres-elo:
    image: postgres:16-alpine
    container_name: tipsharks-postgres-elo
    restart: always
    environment:
      POSTGRES_DB: tipsharks
      POSTGRES_USER: ${POSTGRES_ELO_USER}
      POSTGRES_PASSWORD: ${POSTGRES_ELO_PASSWORD}
    volumes:
      - pg-elo-data:/var/lib/postgresql/data
    networks:
      - tipsharks-network
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_ELO_USER} -d tipsharks"]
      interval: 10s
      timeout: 5s
      retries: 5
    deploy:
      resources:
        limits:
          memory: 1G

  redis:
    image: redis:7-alpine
    container_name: tipsharks-redis
    restart: always
    command: redis-server --appendonly yes --maxmemory 256mb --maxmemory-policy allkeys-lru
    volumes:
      - redis-data:/data
    networks:
      - tipsharks-network
    healthcheck:
      test: ["CMD", "redis-cli", "ping"]
      interval: 10s
      timeout: 5s
      retries: 5
    deploy:
      resources:
        limits:
          memory: 256M

  mongo:
    image: mongo:7
    container_name: tipsharks-mongo
    restart: always
    environment:
      MONGO_INITDB_ROOT_USERNAME: ${MONGO_ROOT_USER}
      MONGO_INITDB_ROOT_PASSWORD: ${MONGO_ROOT_PASSWORD}
    volumes:
      - mongo-data:/data/db
    networks:
      - tipsharks-network
    healthcheck:
      test: echo 'db.runCommand("ping").ok' | mongosh localhost:27017/test --quiet
      interval: 10s
      timeout: 5s
      retries: 5
    deploy:
      resources:
        limits:
          memory: 512M

  # ==========================================================================
  # Application services
  # ==========================================================================

  tab-api-ingest:
    build:
      context: ./tab-api-ingest
      dockerfile: Dockerfile
    container_name: tipsharks-ingest
    restart: always
    environment:
      NODE_ENV: production
      DATABASE_URL: ${INGEST_DATABASE_URL}
      REDIS_URL: redis://redis:6379
      TAB_API_BASE_URL: ${TAB_API_BASE_URL}
      TAB_API_KEY: ${TAB_API_KEY}
      LOG_LEVEL: warn
      OTEL_EXPORTER_OTLP_ENDPOINT: ${OTEL_ENDPOINT:-}
      OTEL_SERVICE_NAME: tab-api-ingest
      METRICS_PORT: 9090
      HEALTH_CHECK_PORT: 8080
    ports:
      - "9090:9090"
    networks:
      - tipsharks-network
    depends_on:
      postgres-ingest:
        condition: service_healthy
      redis:
        condition: service_healthy
    deploy:
      replicas: 1
      resources:
        limits:
          memory: 512M

  tipsharks-elo-api:
    build:
      context: ./tipsharks-elo-api
      dockerfile: infrastructure/docker/Dockerfile.api
    container_name: tipsharks-elo-api
    restart: always
    environment:
      DATABASE_URL: ${ELO_DATABASE_URL}
      TAB_BASE_URL: ${TAB_BASE_URL}
      TAB_MOCK_MODE: "false"
      LOG_LEVEL: INFO
      LOG_FORMAT: json
      API_HOST: 0.0.0.0
      API_PORT: 8000
      API_ADMIN_TOKEN: ${API_ADMIN_TOKEN}
      API_CORS_ALLOW_ORIGINS: ${CORS_ORIGINS}
    ports:
      - "8000:8000"
    networks:
      - tipsharks-network
    depends_on:
      postgres-elo:
        condition: service_healthy
    deploy:
      replicas: 2
      resources:
        limits:
          memory: 1G

  tipsharks-client-backend:
    build:
      context: ./tipsharks-client/backend
      dockerfile: Dockerfile
    container_name: tipsharks-client-backend
    restart: always
    environment:
      MONGO_URL: ${MONGO_URL}
      DB_NAME: ${MONGO_DB_NAME}
      ELO_API_URL: http://tipsharks-elo-api:8000
    ports:
      - "8001:8001"
    networks:
      - tipsharks-network
    depends_on:
      mongo:
        condition: service_healthy
    deploy:
      replicas: 2
      resources:
        limits:
          memory: 512M

  # Worker for background jobs
  tipsharks-worker:
    build:
      context: ./tipsharks-elo-api
      dockerfile: infrastructure/docker/Dockerfile.worker
    container_name: tipsharks-worker
    restart: always
    environment:
      DATABASE_URL: ${ELO_DATABASE_URL}
      TAB_BASE_URL: ${TAB_BASE_URL}
      TAB_MOCK_MODE: "false"
    networks:
      - tipsharks-network
    depends_on:
      postgres-elo:
        condition: service_healthy
    deploy:
      replicas: 1
      resources:
        limits:
          memory: 2G

  # ==========================================================================
  # Reverse proxy
  # ==========================================================================

  nginx:
    image: nginx:alpine
    container_name: tipsharks-nginx
    restart: always
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./infrastructure/nginx/nginx.conf:/etc/nginx/nginx.conf:ro
      - ./infrastructure/nginx/ssl:/etc/nginx/ssl:ro
    networks:
      - tipsharks-network
    depends_on:
      - tab-api-ingest
      - tipsharks-elo-api
      - tipsharks-client-backend

# ==========================================================================
# Persistent volumes
# ==========================================================================

volumes:
  pg-ingest-data:
  pg-elo-data:
  redis-data:
  mongo-data:

# ==========================================================================
# Network
# ==========================================================================

networks:
  tipsharks-network:
    driver: bridge
