version: "3.8"

# ============================================================================
# EasyStream - Production Docker Compose Configuration
# ============================================================================
# Usage: docker-compose -f docker-compose.prod.yml up -d
#
# IMPORTANT: Before deployment:
# 1. Copy .env.production to .env and fill in all values
# 2. Generate secure secrets for all services
# 3. Set up SSL/TLS certificates
# 4. Configure external volumes for data persistence
# 5. Set up monitoring and logging
# ============================================================================

services:

  db:
    image: mariadb:10.6
    container_name: easystream-db-prod
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD_FILE: /run/secrets/db_root_password
      MYSQL_DATABASE: ${DB_NAME:-easystream}
      MYSQL_USER: ${DB_USER:-easystream}
      MYSQL_PASSWORD_FILE: /run/secrets/db_password
    ports:
      - "127.0.0.1:3306:3306"  # Only bind to localhost
    volumes:
      - db_data:/var/lib/mysql
      - ./__install/easystream.sql:/docker-entrypoint-initdb.d/1-main_schema.sql:ro
      - ./__install/add_advanced_features.sql:/docker-entrypoint-initdb.d/2-advanced_features.sql:ro
      - ./deploy/init_settings.sql:/docker-entrypoint-initdb.d/3-init_settings.sql:ro
      - ./deploy/backup:/backup  # For database backups
    secrets:
      - db_root_password
      - db_password
    healthcheck:
      test: ["CMD-SHELL", "mysqladmin ping -h 127.0.0.1 -u ${DB_USER:-easystream} --silent || exit 1"]
      start_period: 120s
      interval: 30s
      timeout: 10s
      retries: 5
    networks:
      - backend
    logging:
      driver: "json-file"
      options:
        max-size: "10m"
        max-file: "3"

  php:
    build:
      context: .
      dockerfile: Dockerfile.php
      args:
        PHP_VERSION: 8.2
    image: easystream-php:production
    container_name: easystream-php-prod
    restart: always
    working_dir: /srv/easystream
    environment:
      TZ: ${TZ:-UTC}
      DB_HOST: db
      DB_NAME: ${DB_NAME:-easystream}
      DB_USER: ${DB_USER:-easystream}
      DB_PASS_FILE: /run/secrets/db_password
      REDIS_HOST: redis
      REDIS_PORT: 6379
      REDIS_DB: 0
      MAIN_URL: ${MAIN_URL}
      DEBUG: "false"
      APP_ENV: production
      PHP_MEMORY_LIMIT: 512M
      PHP_UPLOAD_MAX_FILESIZE: 256M
      PHP_POST_MAX_SIZE: 256M
    volumes:
      - ./:/srv/easystream:ro  # Read-only for security
      - app_uploads:/srv/easystream/f_data/uploads
      - app_cache:/srv/easystream/f_data/cache
      - app_logs:/srv/easystream/f_data/logs
      - rtmp_hls:/var/www/hls:ro
      - rtmp_rec:/mnt/rec:ro
    secrets:
      - db_password
      - api_key
      - jwt_secret
      - encryption_key
    depends_on:
      db:
        condition: service_healthy
      redis:
        condition: service_healthy
    networks:
      - frontend
      - backend
    logging:
      driver: "json-file"
      options:
        max-size: "10m"
        max-file: "5"

  caddy:
    image: caddy:2-alpine
    container_name: easystream-caddy-prod
    restart: always
    depends_on:
      php:
        condition: service_started
      srs:
        condition: service_started
    ports:
      - "80:80"
      - "443:443"
      - "443:443/udp"  # HTTP/3
    volumes:
      - ./Caddyfile:/etc/caddy/Caddyfile:ro
      - ./:/srv/easystream:ro
      - rtmp_hls:/var/www/hls:ro
      - caddy_data:/data
      - caddy_config:/config
      - ./deploy/ssl:/ssl:ro  # For custom SSL certificates
    networks:
      - frontend
    logging:
      driver: "json-file"
      options:
        max-size: "10m"
        max-file: "3"
    healthcheck:
      test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:80/health"]
      interval: 30s
      timeout: 10s
      retries: 3

  srs:
    image: ossrs/srs:5
    container_name: easystream-srs-prod
    restart: always
    ports:
      - "1935:1935"   # RTMP ingest
      - "1985:1985"   # HTTP API
      - "8080:8080"   # HTTP Server
    volumes:
      - ./deploy/srs.conf:/usr/local/srs/conf/srs.conf:ro
      - rtmp_hls:/srs/hls
      - rtmp_rec:/srs/rec
      - srs_logs:/usr/local/srs/objs/logs
    command: ["/usr/local/srs/objs/srs", "-c", "/usr/local/srs/conf/srs.conf"]
    networks:
      - frontend
      - backend
    logging:
      driver: "json-file"
      options:
        max-size: "10m"
        max-file: "3"

  redis:
    image: redis:7-alpine
    container_name: easystream-redis-prod
    restart: always
    ports:
      - "127.0.0.1:6379:6379"  # Only bind to localhost
    volumes:
      - redis_data:/data
    command: >
      redis-server
      --appendonly yes
      --maxmemory 512mb
      --maxmemory-policy allkeys-lru
      --requirepass ${REDIS_PASSWORD:-}
      --save 900 1
      --save 300 10
      --save 60 10000
    networks:
      - backend
    healthcheck:
      test: ["CMD", "redis-cli", "ping"]
      interval: 30s
      timeout: 10s
      retries: 5
    logging:
      driver: "json-file"
      options:
        max-size: "5m"
        max-file: "3"

  cron:
    build:
      context: .
      dockerfile: Dockerfile.cron
    image: easystream-cron:production
    container_name: easystream-cron-prod
    restart: always
    depends_on:
      php:
        condition: service_started
    environment:
      TZ: ${TZ:-UTC}
      DB_HOST: db
      DB_NAME: ${DB_NAME:-easystream}
      DB_USER: ${DB_USER:-easystream}
      DB_PASS_FILE: /run/secrets/db_password
      CRON_BASE_URL: ${MAIN_URL}
      CRON_SSK_FILE: /run/secrets/cron_secret
      VOD_REC_PATH: /mnt/rec
      REDIS_HOST: redis
      REDIS_PORT: 6379
      REDIS_DB: 0
    volumes:
      - ./:/srv/easystream:ro
      - rtmp_rec:/mnt/rec:ro
      - cron_logs:/var/log/cron
    secrets:
      - db_password
      - cron_secret
    networks:
      - backend
    logging:
      driver: "json-file"
      options:
        max-size: "5m"
        max-file: "3"

  queue-worker:
    build:
      context: .
      dockerfile: Dockerfile.php
    image: easystream-php:production
    container_name: easystream-worker-prod
    restart: always
    depends_on:
      db:
        condition: service_healthy
      redis:
        condition: service_healthy
    environment:
      TZ: ${TZ:-UTC}
      DB_HOST: db
      DB_NAME: ${DB_NAME:-easystream}
      DB_USER: ${DB_USER:-easystream}
      DB_PASS_FILE: /run/secrets/db_password
      REDIS_HOST: redis
      REDIS_PORT: 6379
      WORKER_QUEUES: ${WORKER_QUEUES:-default,video,email,notifications}
      WORKER_SLEEP: ${WORKER_SLEEP:-3}
      WORKER_TIMEOUT: ${WORKER_TIMEOUT:-300}
    volumes:
      - ./:/srv/easystream:ro
      - app_uploads:/srv/easystream/f_data/uploads
      - rtmp_hls:/var/www/hls
      - rtmp_rec:/mnt/rec
    secrets:
      - db_password
    command: php f_scripts/queue_worker.php
    networks:
      - backend
    logging:
      driver: "json-file"
      options:
        max-size: "10m"
        max-file: "5"
    deploy:
      replicas: 2  # Run 2 workers for high availability

  abr:
    image: jrottenberg/ffmpeg:5.1-ubuntu
    container_name: easystream-abr-prod
    restart: always
    entrypoint: ["/bin/bash"]
    command: ["/abr.sh"]
    depends_on:
      srs:
        condition: service_started
    environment:
      ABR_STREAM_KEY: ${ABR_STREAM_KEY:-}
    volumes:
      - rtmp_hls:/var/www/hls
      - ./deploy/abr.sh:/abr.sh:ro
    networks:
      - backend
    logging:
      driver: "json-file"
      options:
        max-size: "5m"
        max-file: "3"

# ============================================================================
# Docker Secrets (Production Security)
# ============================================================================
# Create these files before deployment:
# echo "your_secret" | docker secret create db_root_password -
# echo "your_secret" | docker secret create db_password -
# etc.
# ============================================================================

secrets:
  db_root_password:
    file: ./secrets/db_root_password.txt
  db_password:
    file: ./secrets/db_password.txt
  api_key:
    file: ./secrets/api_key.txt
  jwt_secret:
    file: ./secrets/jwt_secret.txt
  encryption_key:
    file: ./secrets/encryption_key.txt
  cron_secret:
    file: ./secrets/cron_secret.txt

# ============================================================================
# Persistent Volumes
# ============================================================================

volumes:
  db_data:
    driver: local
    driver_opts:
      type: none
      o: bind
      device: /var/lib/easystream/db
  redis_data:
    driver: local
  app_uploads:
    driver: local
    driver_opts:
      type: none
      o: bind
      device: /var/lib/easystream/uploads
  app_cache:
    driver: local
  app_logs:
    driver: local
    driver_opts:
      type: none
      o: bind
      device: /var/log/easystream
  rtmp_hls:
    driver: local
  rtmp_rec:
    driver: local
    driver_opts:
      type: none
      o: bind
      device: /var/lib/easystream/recordings
  srs_logs:
    driver: local
  cron_logs:
    driver: local
  caddy_data:
    driver: local
  caddy_config:
    driver: local

# ============================================================================
# Networks
# ============================================================================

networks:
  frontend:
    driver: bridge
  backend:
    driver: bridge
    internal: true  # Backend network not accessible from outside
