version: '3.8'

services:
  memcached:
    image: memcached:1.6-alpine
    container_name: memcached-prod
    command: memcached -m 64 -v
    restart: unless-stopped
    networks:
      - app_network
    deploy:
      resources:
        limits:
          memory: 128M
        reservations:
          memory: 64M

  memcached-exporter:
    image: prom/memcached-exporter:v0.13.0
    command:
      - '--memcached.address=memcached:11211'
    ports:
      - "9150:9150"
    depends_on:
      - memcached
    networks:
      - app_network
    restart: unless-stopped

  prometheus:
    image: prom/prometheus:v2.52.0
    container_name: prometheus-prod
    ports:
      - "9090:9090"
    volumes:
      - prometheus_data:/prometheus
      - ./prometheus/prometheus.yml:/etc/prometheus/prometheus.yml:ro
    command:
      - '--config.file=/etc/prometheus/prometheus.yml'
      - '--storage.tsdb.path=/prometheus'
      - '--web.console.libraries=/etc/prometheus/console_libraries'
      - '--web.console.templates=/etc/prometheus/consoles'
      - '--storage.tsdb.retention.time=30d'
      - '--web.enable-lifecycle'
    depends_on:
      - memcached-exporter
    networks:
      - app_network
    restart: unless-stopped
    deploy:
      resources:
        limits:
          memory: 512M
        reservations:
          memory: 256M

  grafana:
    image: grafana/grafana:11.2.0
    container_name: grafana-prod
    ports:
      - "3001:3000"  # Changed from 3000 to avoid conflict
    environment:
      - GF_SECURITY_ADMIN_USER=admin
      - GF_SECURITY_ADMIN_PASSWORD=${GRAFANA_PASSWORD}
      - GF_USERS_ALLOW_SIGN_UP=false
      - GF_INSTALL_PLUGINS=grafana-piechart-panel
      - GF_SECURITY_DISABLE_GRAVATAR=true
      - GF_SERVER_DOMAIN=grafana.courierdepot.net
      - GF_SERVER_ROOT_URL=%(protocol)s://%(domain)s/
    volumes:
      - grafana_data:/var/lib/grafana
      - ./grafana/provisioning:/etc/grafana/provisioning:ro
    depends_on:
      - prometheus
    networks:
      - app_network
    restart: unless-stopped
    deploy:
      resources:
        limits:
          memory: 256M
        reservations:
          memory: 128M

  db:
    image: postgres:15-alpine
    container_name: postgres_db-prod
    environment:
      POSTGRES_USER: ${POSTGRES_USER}
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
      POSTGRES_DB: ${POSTGRES_DB}
      POSTGRES_INITDB_ARGS: "--encoding=UTF8 --lc-collate=C --lc-ctype=C"
    volumes:
      - postgres_data:/var/lib/postgresql/data
    networks:
      - app_network
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER}"]
      interval: 10s
      timeout: 10s
      retries: 5
      start_period: 30s
    restart: unless-stopped
    deploy:
      resources:
        limits:
          memory: 1G
        reservations:
          memory: 512M
    command: >
      postgres
      -c shared_preload_libraries=pg_stat_statements
      -c pg_stat_statements.track=all
      -c max_connections=100
      -c shared_buffers=256MB

  backend:
    build:
      context: ./backend
      dockerfile: Dockerfile.prod
    container_name: fastapi_backend-prod
    working_dir: /app
    environment:
      - DATABASE_URL=postgresql+asyncpg://${POSTGRES_USER}:${POSTGRES_PASSWORD}@db/${POSTGRES_DB}
      - MEMCACHED_URL=memcached:11211
      - DEBUG=false
      - CLAMD_HOST=clamav
      - CLAMD_PORT=3310
      - PYTHONPATH=/app
      - ENVIRONMENT=production
      - LOG_LEVEL=INFO
      - CORS_ORIGINS=https://app.courierdepot.net
    volumes:
      - uploads:/app/public/uploads
    networks:
      - app_network
    depends_on:
      db:
        condition: service_healthy
      memcached:
        condition: service_started
      clamav:
        condition: service_started
    restart: unless-stopped
    deploy:
      resources:
        limits:
          memory: 512M
        reservations:
          memory: 256M
    healthcheck:
      test: ["CMD-SHELL", "curl -f http://localhost:8000/health || exit 1"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 40s
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.backend.rule=Host(`api.courierdepot.net`)"
      - "traefik.http.routers.backend.entrypoints=web"
      - "traefik.http.services.backend.loadbalancer.server.port=8000"

  clamav:
    image: clamav/clamav:stable
    container_name: clamav-prod
    environment:
      - CLAMD_STARTUP_TIMEOUT=300
      - CLAMAV_NO_FRESHCLAMD=false
    volumes:
      - uploads:/app/public/uploads
      - clamav_data:/var/lib/clamav
    networks:
      - app_network
    restart: unless-stopped
    deploy:
      resources:
        limits:
          memory: 1G
        reservations:
          memory: 512M

  frontend:
    build:
      context: ./frontend
      dockerfile: Dockerfile.prod
    container_name: nuxt_frontend-prod
    working_dir: /app
    environment:
      - NUXT_PUBLIC_API_BASE_URL=https://api.courierdepot.net
      - API_BASE_URL=http://backend:8000
      - NODE_ENV=production
    networks:
      - app_network
    depends_on:
      - backend
    restart: unless-stopped
    deploy:
      resources:
        limits:
          memory: 512M
        reservations:
          memory: 256M
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.frontend.rule=Host(`app.courierdepot.net`)"
      - "traefik.http.routers.frontend.entrypoints=web"
      - "traefik.http.services.frontend.loadbalancer.server.port=3000"

  traefik:
    image: traefik:v3.0
    container_name: traefik-prod
    command:
      - "--api.dashboard=true"
      - "--providers.docker=true"
      - "--providers.docker.exposedbydefault=false"
      - "--entrypoints.web.address=:8080"  # Use port 8080 instead of 80
      - "--entrypoints.websecure.address=:8443"  # Use port 8443 instead of 443
      # Remove Let's Encrypt since cPanel handles SSL
    ports:
      - "8080:8080"    # Traefik HTTP
      - "8443:8443"    # Traefik HTTPS
    volumes:
      - "/var/run/docker.sock:/var/run/docker.sock:ro"
    networks:
      - app_network
    restart: unless-stopped
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.traefik.rule=Host(`traefik.courierdepot.net`)"
      - "traefik.http.routers.traefik.entrypoints=web"
      - "traefik.http.services.traefik.loadbalancer.server.port=8080"
      - "traefik.http.routers.traefik.service=api@internal"

volumes:
  postgres_data:
    driver: local
  grafana_data:
    driver: local
  prometheus_data:
    driver: local
  clamav_data:
    driver: local
  uploads:
    driver: local

networks:
  app_network:
    driver: bridge