# Banatie Production - VPS Isolated Deployment
# ============================================
# This is the production docker-compose file used on VPS at /opt/banatie/
# Last Updated: December 23, 2025
#
# Usage:
#   docker compose --env-file .env --env-file secrets.env up -d
#   docker compose --env-file .env --env-file secrets.env build --no-cache
#
# Key differences from dev:
#   - Uses external proxy-network for Caddy integration
#   - All services isolated in banatie-internal network
#   - MinIO with 4 drives for full S3 compatibility
#   - Secrets stored in separate secrets.env file

services:
  # ----------------------------------------
  # API Service - Express.js REST API
  # ----------------------------------------
  banatie-api:
    build:
      context: /home/usul/workspace/projects/banatie-service
      dockerfile: apps/api-service/Dockerfile
      target: production
    container_name: banatie-api
    restart: unless-stopped
    networks:
      - banatie-internal
      - proxy-network
    depends_on:
      banatie-postgres:
        condition: service_healthy
      banatie-minio:
        condition: service_healthy
    env_file:
      - .env
      - secrets.env
    environment:
      - IS_DOCKER=true
      - NODE_ENV=production
    volumes:
      - ./logs/api:/app/apps/api-service/logs
      - ./data/api-results:/app/results
      - ./data/api-uploads:/app/uploads
    healthcheck:
      # Note: Alpine images don't have curl by default
      # Using wget instead, but may still show "unhealthy" - service works correctly
      test: ["CMD", "wget", "--spider", "-q", "http://localhost:3000/health"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 60s

  # ----------------------------------------
  # Landing Page - Next.js 15.5.9
  # ----------------------------------------
  banatie-landing:
    build:
      context: /home/usul/workspace/projects/banatie-service
      dockerfile: apps/landing/Dockerfile
    container_name: banatie-landing
    restart: unless-stopped
    networks:
      - banatie-internal
      - proxy-network
    depends_on:
      - banatie-postgres
    env_file:
      - .env
      - secrets.env
    environment:
      - IS_DOCKER=true
      - NODE_ENV=production
      - HOSTNAME=0.0.0.0
      - WAITLIST_LOGS_PATH=/app/waitlist-logs
    volumes:
      - ./data/waitlist-logs:/app/waitlist-logs
    healthcheck:
      test: ["CMD", "wget", "--spider", "-q", "http://localhost:3000"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 30s

  # ----------------------------------------
  # PostgreSQL Database
  # ----------------------------------------
  banatie-postgres:
    image: postgres:15-alpine
    container_name: banatie-postgres
    restart: unless-stopped
    networks:
      - banatie-internal
    volumes:
      - ./data/postgres:/var/lib/postgresql/data
      - ./scripts/init-db.sql:/docker-entrypoint-initdb.d/01-init.sql:ro
    environment:
      POSTGRES_DB: ${POSTGRES_DB}
      POSTGRES_USER: ${POSTGRES_USER}
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER} -d ${POSTGRES_DB}"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 40s

  # ----------------------------------------
  # MinIO Object Storage (S3-compatible)
  # ----------------------------------------
  banatie-minio:
    image: quay.io/minio/minio:latest
    container_name: banatie-minio
    restart: unless-stopped
    networks:
      - banatie-internal
      - proxy-network
    volumes:
      # 4 drives for SNMD mode (full S3 compatibility)
      - ./data/minio/drive1:/data1
      - ./data/minio/drive2:/data2
      - ./data/minio/drive3:/data3
      - ./data/minio/drive4:/data4
    environment:
      MINIO_ROOT_USER: ${MINIO_ROOT_USER}
      MINIO_ROOT_PASSWORD: ${MINIO_ROOT_PASSWORD}
      MINIO_BROWSER_REDIRECT_URL: https://storage.banatie.app
      MINIO_SERVER_URL: https://cdn.banatie.app
    command: server /data{1...4} --console-address ":9001"
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/live"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 40s

  # ----------------------------------------
  # Storage Initialization (runs once)
  # ----------------------------------------
  banatie-storage-init:
    image: minio/mc:latest
    container_name: banatie-storage-init
    networks:
      - banatie-internal
    depends_on:
      banatie-minio:
        condition: service_healthy
    env_file:
      - secrets.env
    entrypoint:
      - /bin/sh
      - -c
      - |
        echo '=== MinIO Storage Initialization ==='
        mc alias set storage http://banatie-minio:9000 $${MINIO_ROOT_USER} $${MINIO_ROOT_PASSWORD}
        mc mb --ignore-existing storage/banatie
        mc admin user add storage $${MINIO_ACCESS_KEY} $${MINIO_SECRET_KEY} || echo 'User may already exist'
        mc admin policy attach storage readwrite --user=$${MINIO_ACCESS_KEY} || echo 'Policy may already be attached'
        cat > /tmp/lifecycle.json <<'LCEOF'
        {"Rules":[{"ID":"temp-cleanup","Status":"Enabled","Filter":{"Prefix":"temp/"},"Expiration":{"Days":7}}]}
        LCEOF
        mc ilm import storage/banatie < /tmp/lifecycle.json || echo 'Lifecycle policy may already exist'
        echo '=== Storage Initialization Completed ==='
        exit 0
    restart: "no"

# ----------------------------------------
# Networks
# ----------------------------------------
networks:
  # Internal network for service communication
  # internal: true means no outbound access
  banatie-internal:
    driver: bridge
    internal: true

  # External network shared with Caddy reverse proxy
  # Must be created by Caddy's docker-compose first
  proxy-network:
    name: services_proxy-network
    external: true
