---
# SousChef Docker Compose Configuration
#
# Database Backend Selection:
#   - PostgreSQL (default): Robust production-ready database server
#     $ docker compose up
#
#   - SQLite: Lightweight embedded database (set SOUSCHEF_DB_BACKEND=sqlite in .env)
#     Still uses PostgreSQL service, but data stored locally in SQLite
#
# PostgreSQL service is always started. Configure which backend via SOUSCHEF_DB_BACKEND.
#
services:
  souschef-ui:
    build:
      context: .
      dockerfile: Dockerfile.ui
      args:
        PYTHON_VERSION: "3.14.3"
        POETRY_VERSION: "2.3.2"
    ports:
      - "9999:9999"
    env_file:
      - .env
    environment:
      - PYTHONPATH=/app
      - STREAMLIT_SERVER_ADDRESS=0.0.0.0
      - STREAMLIT_SERVER_PORT=9999
      - STREAMLIT_SERVER_HEADLESS=true
      - STREAMLIT_LOGGER_LEVEL=info
      - STREAMLIT_SERVER_LOGGER_LEVEL=info
      - PYTHONUNBUFFERED=1
      - STREAMLIT_SERVER_ENABLE_XSRF_PROTECTION=true
      - STREAMLIT_BROWSER_GATHER_USAGE_STATS=false
      # Database configuration
      - SOUSCHEF_DB_BACKEND=${SOUSCHEF_DB_BACKEND:-postgres}
      - SOUSCHEF_DB_HOST=${SOUSCHEF_DB_HOST:-postgres}
      - SOUSCHEF_DB_PORT=${SOUSCHEF_DB_PORT:-5432}
      - SOUSCHEF_DB_NAME=${SOUSCHEF_DB_NAME:-souschef}
      - SOUSCHEF_DB_USER=${SOUSCHEF_DB_USER:-souschef}
      - SOUSCHEF_DB_PASSWORD=${SOUSCHEF_DB_PASSWORD:?SOUSCHEF_DB_PASSWORD is required}
      - SOUSCHEF_DB_SSLMODE=${SOUSCHEF_DB_SSLMODE:-require}
      # Blob storage configuration (S3-compatible)
      - SOUSCHEF_STORAGE_BACKEND=${SOUSCHEF_STORAGE_BACKEND:-s3}
      - SOUSCHEF_S3_BUCKET=${SOUSCHEF_S3_BUCKET:-souschef}
      - SOUSCHEF_S3_REGION=${SOUSCHEF_S3_REGION:-us-east-1}
      - SOUSCHEF_S3_ENDPOINT=${SOUSCHEF_S3_ENDPOINT:-http://minio:9000}
      - SOUSCHEF_S3_ACCESS_KEY=${SOUSCHEF_S3_ACCESS_KEY:?SOUSCHEF_S3_ACCESS_KEY is required}
      - SOUSCHEF_S3_SECRET_KEY=${SOUSCHEF_S3_SECRET_KEY:?SOUSCHEF_S3_SECRET_KEY is required}
    logging:
      driver: "json-file"
      options:
        max-size: "10m"
        max-file: "3"
        labels: "service=souschef-ui"
    healthcheck:
      test: ["CMD", "python", "-m", "souschef.ui.health_check"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 40s
    mem_limit: 1g
    cpus: "0.5"
    security_opt:
      - no-new-privileges:true
    cap_drop:
      - ALL
    user: "1001:1001"
    read_only: true
    tmpfs:
      # Temporary filesystems - writable directories for runtime use
      - /tmp:noexec,nosuid,size=256m
      - /run:noexec,nosuid,size=50m
      - /app/.cache:noexec,nosuid,size=256m
      - /app/.streamlit:noexec,nosuid,size=50m
      - /app/.tmp:noexec,nosuid,size=50m
    networks:
      - souschef-public
      - souschef-internal
    depends_on:
      postgres:
        condition: service_healthy
      minio:
        condition: service_healthy
    restart: unless-stopped
    container_name: souschef-ui

  postgres:
    image: postgres:16-alpine
    container_name: souschef-postgres
    environment:
      POSTGRES_DB: ${SOUSCHEF_DB_NAME:-souschef}
      POSTGRES_USER: ${SOUSCHEF_DB_USER:-souschef}
      POSTGRES_PASSWORD: ${SOUSCHEF_DB_PASSWORD:?SOUSCHEF_DB_PASSWORD is required}
    ports:
      - "127.0.0.1:5432:5432"
    volumes:
      - postgres-data:/var/lib/postgresql/data
    networks:
      - souschef-internal
    restart: unless-stopped
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U ${SOUSCHEF_DB_USER:-souschef} -d ${SOUSCHEF_DB_NAME:-souschef}"]
      interval: 10s
      timeout: 5s
      retries: 5

  minio:
    image: minio/minio:latest
    container_name: souschef-minio
    environment:
      MINIO_ROOT_USER: ${SOUSCHEF_S3_ACCESS_KEY:?SOUSCHEF_S3_ACCESS_KEY is required}
      MINIO_ROOT_PASSWORD: ${SOUSCHEF_S3_SECRET_KEY:?SOUSCHEF_S3_SECRET_KEY is required}
    ports:
      - "127.0.0.1:9000:9000"
      - "127.0.0.1:9001:9001"
    volumes:
      - minio-data:/data
    command: server /data --console-address ":9001"
    networks:
      - souschef-internal
    restart: unless-stopped
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/live"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 10s

volumes:
  # SQLite database volume - only needed if SOUSCHEF_DB_BACKEND=sqlite
  # Data survives container restarts
  # Configure via SOUSCHEF_DATA_DIR in .env (default: ./data/souschef)
  # souschef-data:
  #   driver: local
  #   driver_opts:
  #     type: none
  #     o: bind
  #     device: ${SOUSCHEF_DATA_DIR:-./data/souschef}

  # Local blob storage volume - only needed if SOUSCHEF_STORAGE_BACKEND=local
  # Stores generated artefacts and conversions locally
  # Configure via SOUSCHEF_STORAGE_DIR in .env (default: ./data/storage)
  # souschef-storage:
  #   driver: local
  #   driver_opts:
  #     type: none
  #     o: bind
  #     device: ${SOUSCHEF_STORAGE_DIR:-./data/storage}
  # PostgreSQL database storage (active by default)
  # Configure via POSTGRES_DATA_DIR in .env (default: ./data/postgres)
  postgres-data:
    driver: local
    driver_opts:
      type: none
      o: bind
      device: ${POSTGRES_DATA_DIR:-./data/postgres}
  # MinIO object storage
  # Configure via MINIO_DATA_DIR in .env (default: ./data/minio)
  minio-data:
    driver: local
    driver_opts:
      type: none
      o: bind
      device: ${MINIO_DATA_DIR:-./data/minio}

networks:
  souschef-public:
    driver: bridge
  souschef-internal:
    driver: bridge
    internal: true

