# Docker Compose configuration for Stream Processing Django Application
# This file defines the multi-container setup for the streaming application

services:
  # PostgreSQL database service
  # Primary database for storing application data
  db:
    image: postgres:17-alpine
    container_name: stream_postgres
    restart: unless-stopped
    environment:
      # Database configuration from environment variables
      POSTGRES_DB: ${DB_NAME:-stream_db}
      POSTGRES_USER: ${DB_USER:-postgres}
      POSTGRES_PASSWORD: ${DB_PASSWORD:-postgres}
      # Performance tuning
      POSTGRES_INITDB_ARGS: "--encoding=UTF-8 --lc-collate=C --lc-ctype=C"
    volumes:
      # Persistent storage for database data
      - postgres_data:/var/lib/postgresql/data
      # Custom initialization scripts
      - ./docker/postgres/init.sql:/docker-entrypoint-initdb.d/init.sql 
    networks:
      - stream_network
    healthcheck:
      # Health check to ensure database is ready
      test: ["CMD-SHELL", "pg_isready -U ${DB_USER:-postgres}"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 30s 
    security_opt:
      - no-new-privileges:true

  # Redis service for Celery message broker
  # Used for task queue management and caching
  redis:
    image: redis:7.4-alpine
    container_name: stream_redis
    restart: unless-stopped  
    volumes:
      # Persistent storage for Redis data
      - redis_data:/data
      # Redis configuration for security and performance
      - ./docker/redis/redis.conf:/usr/local/etc/redis/redis.conf
    networks:
      - stream_network
    command: |
      sh -c '
        # Fix permissions for Redis data directory
        chown -R 1000:1000 /data
        chmod -R 755 /data
        # Start Redis as root (will drop privileges internally)
        exec redis-server /usr/local/etc/redis/redis.conf
      '
    healthcheck:
      # Health check for Redis availability
      test: ["CMD", "redis-cli", "ping"]
      interval: 30s
      timeout: 10s
      retries: 5
      start_period: 10s 
    security_opt:
      - no-new-privileges:true

  # Main Django web application
  # Handles web interface and API endpoints
  web:
    build:
      context: .
      dockerfile: docker/web.Dockerfile
      target: ${BUILD_TARGET:-development}
      args:
        - BUILDKIT_INLINE_CACHE=1
    container_name: stream_web
    restart: unless-stopped
    user: "${USER_ID:-1000}:${GROUP_ID:-1000}"
    ports:
      - "8000:8000"
    volumes: 
      # Application code volume for development
      - ./src:/app
      # Media files volume
      - ./src/media:/app/media
      # Logs volume
      - ./src/logs:/app/logs
      # Static files volume - commented out to avoid permission issues
      # - ./src/staticfiles:/app/staticfiles 
    environment:
      # Environment variables for Django configuration
      - DEBUG=${DEBUG:-True}
      - SECRET_KEY=${SECRET_KEY:-hr1@u!@p1+b&*&i=*uv7_vu6@!=vgml8jhhoai=pc%r1ed+2@z}
      - DB_NAME=${DB_NAME:-stream_db}
      - DB_USER=${DB_USER:-postgres}
      - DB_PASSWORD=${DB_PASSWORD:-postgres}
      - DB_HOST=db
      - DB_PORT=5432
      - REDIS_URL=redis://redis:6379/0
      - CELERY_BROKER_URL=redis://redis:6379/0
      - CELERY_RESULT_BACKEND=redis://redis:6379/0
      - DEFAULT_ADMIN_USERNAME=${DEFAULT_ADMIN_USERNAME:-admin}
      - DEFAULT_ADMIN_EMAIL=${DEFAULT_ADMIN_EMAIL:-admin@streamprocessor.com}
      - DEFAULT_ADMIN_PASSWORD=${DEFAULT_ADMIN_PASSWORD:-StreamAdmin2024!}
    depends_on:
      db:
        condition: service_healthy
      redis:
        condition: service_healthy
    networks:
      - stream_network
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:8000/health/"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 60s 
    security_opt:
      - no-new-privileges:true
    command: >
      sh -c "python manage.py makemigrations &&
             python manage.py migrate &&
             python manage.py setup_stream_processor --create-sample-data --create-superuser --admin-username=${DEFAULT_ADMIN_USERNAME:-admin} --admin-email=${DEFAULT_ADMIN_EMAIL:-admin@streamprocessor.com} &&
             python manage.py runserver 0.0.0.0:8000"

  # Celery worker for background tasks
  # Handles stream processing, jingle detection, and notifications
  celery_worker:
    build:
      context: .
      dockerfile: docker/worker.Dockerfile
      args:
        - BUILDKIT_INLINE_CACHE=1
    container_name: stream_celery_worker
    restart: unless-stopped
    volumes:
      # Application code volume for development
      - ./src:/app
      # Media files volume
      - ./src/media:/app/media
      # Logs volume
      - ./src/logs:/app/logs
    environment:
      # Same environment variables as web service
      - DEBUG=${DEBUG:-False}
      - SECRET_KEY=${SECRET_KEY:-hr1@u!@p1+b&*&i=*uv7_vu6@!=vgml8jhhoai=pc%r1ed+2@z}
      - DB_NAME=${DB_NAME:-stream_db}
      - DB_USER=${DB_USER:-postgres}
      - DB_PASSWORD=${DB_PASSWORD:-postgres}
      - DB_HOST=db
      - DB_PORT=5432
      - REDIS_URL=redis://redis:6379/0
      - CELERY_BROKER_URL=redis://redis:6379/0
      - CELERY_RESULT_BACKEND=redis://redis:6379/0
    depends_on:
      db:
        condition: service_healthy
      redis:
        condition: service_healthy
      web:
        condition: service_healthy
    networks:
      - stream_network
    healthcheck:
      test: ["CMD", "celery", "-A", "core", "inspect", "ping"]
      interval: 60s
      timeout: 30s
      retries: 3
      start_period: 120s 
    security_opt:
      - no-new-privileges:true
    command: sh -c "celery -A core worker --loglevel=info --concurrency=${CELERY_WORKER_CONCURRENCY:-4} --prefetch-multiplier=${CELERY_WORKER_PREFETCH_MULTIPLIER:-1}"

  # Celery beat scheduler for periodic tasks
  # Manages scheduled tasks like health checks and cleanup
  celery_beat:
    build:
      context: .
      dockerfile: docker/worker.Dockerfile
      args:
        - BUILDKIT_INLINE_CACHE=1
    container_name: stream_celery_beat
    restart: unless-stopped
    volumes:
      # Application code volume for development
      - ./src:/app
      # Media files volume
      - ./src/media:/app/media
      # Logs volume
      - ./src/logs:/app/logs
    environment:
      # Same environment variables as other services
      - DEBUG=${DEBUG:-False}
      - SECRET_KEY=${SECRET_KEY:-hr1@u!@p1+b&*&i=*uv7_vu6@!=vgml8jhhoai=pc%r1ed+2@z}
      - DB_NAME=${DB_NAME:-stream_db}
      - DB_USER=${DB_USER:-postgres}
      - DB_PASSWORD=${DB_PASSWORD:-postgres}
      - DB_HOST=db
      - DB_PORT=5432
      - REDIS_URL=redis://redis:6379/0
      - CELERY_BROKER_URL=redis://redis:6379/0
      - CELERY_RESULT_BACKEND=redis://redis:6379/0
    depends_on:
      db:
        condition: service_healthy
      redis:
        condition: service_healthy
      web:
        condition: service_healthy
    networks:
      - stream_network
    healthcheck:
      test: ["CMD", "celery", "-A", "core", "inspect", "active"]
      interval: 60s
      timeout: 30s
      retries: 3
      start_period: 120s
    security_opt:
      - no-new-privileges:true
    command: sh -c "celery -A core beat --loglevel=info --schedule=/app/logs/celerybeat-schedule"


  # Flower service for monitoring Celery tasks
  # Provides web interface for task monitoring
  flower:
    build:
      context: .
      dockerfile: docker/worker.Dockerfile
      args:
        - BUILDKIT_INLINE_CACHE=1
    container_name: stream_flower
    restart: unless-stopped
    ports:
      - "5555:5555"
    environment:
      # Celery broker configuration for Flower
      - CELERY_BROKER_URL=redis://redis:6379/0
      - CELERY_RESULT_BACKEND=redis://redis:6379/0
    depends_on:
      redis:
        condition: service_healthy
      celery_worker:
        condition: service_healthy
    networks:
      - stream_network
    healthcheck:
      test: ["CMD", "curl", "-f", "-u", "admin:flower123", "http://localhost:5555/"]
      interval: 60s
      timeout: 10s
      retries: 3
      start_period: 30s 
    security_opt:
      - no-new-privileges:true
    command: sh -c "celery -A core flower --port=5555 --basic_auth=${FLOWER_BASIC_AUTH:-admin:flower123}"


# Named volumes for persistent data storage
volumes:
  # PostgreSQL database data
  postgres_data:
    driver: local
  # Redis data storage
  redis_data:
    driver: local 

# Network configuration for service communication
networks:
  stream_network:
    driver: bridge
