x-defaults: &defaults
  restart: unless-stopped
  logging:
    driver: json-file
    options:
      max-size: 100m
      max-file: '3'

services:
  postgres:
    <<: *defaults
    image: ${GLOBAL_REGISTRY:-}postgres:${POSTGRES_VERSION:-17.6-alpine}
    environment:
      TZ: ${TZ:-UTC}
      POSTGRES_USER: ${POSTGRES_USER:-mlflow}
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-mlflow}
      POSTGRES_DB: ${POSTGRES_DB:-mlflow}
    volumes:
      - postgres_data:/var/lib/postgresql/data
    deploy:
      resources:
        limits:
          cpus: ${POSTGRES_MLFLOW_CPU_LIMIT:-1.0}
          memory: ${POSTGRES_MLFLOW_MEMORY_LIMIT:-1G}
        reservations:
          cpus: ${POSTGRES_MLFLOW_CPU_RESERVATION:-0.1}
          memory: ${POSTGRES_MLFLOW_MEMORY_RESERVATION:-512M}
    healthcheck:
      test: [CMD-SHELL, 'pg_isready -U ${POSTGRES_USER:-mlflow}']
      interval: 10s
      timeout: 5s
      retries: 5
      start_period: 30s

  minio:
    <<: *defaults
    image: ${GLOBAL_REGISTRY:-}minio/minio:${MINIO_VERSION:-RELEASE.2025-01-07T16-13-09Z}
    command: server /data --console-address ":9001"
    environment:
      TZ: ${TZ:-UTC}
      MINIO_ROOT_USER: ${MINIO_ROOT_USER:-minio}
      MINIO_ROOT_PASSWORD: ${MINIO_ROOT_PASSWORD:-minio123}
    ports:
      - '${MINIO_PORT_OVERRIDE:-9000}:9000'
      - '${MINIO_CONSOLE_PORT_OVERRIDE:-9001}:9001'
    volumes:
      - minio_data:/data
    deploy:
      resources:
        limits:
          cpus: ${MINIO_MLFLOW_CPU_LIMIT:-1.0}
          memory: ${MINIO_MLFLOW_MEMORY_LIMIT:-1G}
        reservations:
          cpus: ${MINIO_MLFLOW_CPU_RESERVATION:-0.1}
          memory: ${MINIO_MLFLOW_MEMORY_RESERVATION:-512M}
    healthcheck:
      test: [CMD, curl, -f, 'http://localhost:9000/minio/health/live']
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 30s

  minio-init:
    <<: *defaults
    image: ${GLOBAL_REGISTRY:-}minio/mc:${MINIO_MC_VERSION:-RELEASE.2025-01-07T17-25-52Z}
    depends_on:
      minio:
        condition: service_healthy
    entrypoint: >
      /bin/sh -c "
      sleep 5;
      /usr/bin/mc config host add minio http://minio:9000 ${MINIO_ROOT_USER:-minio} ${MINIO_ROOT_PASSWORD:-minio123};
      /usr/bin/mc mb minio/${MINIO_BUCKET:-mlflow} --ignore-existing;
      exit 0;
      "
    restart: no

  mlflow:
    <<: *defaults
    image: ${GHCR_IO_REGISTRY:-ghcr.io}/mlflow/mlflow:${MLFLOW_VERSION:-v2.20.2}
    depends_on:
      postgres:
        condition: service_healthy
      minio:
        condition: service_healthy
      minio-init:
        condition: service_completed_successfully
    ports:
      - '${MLFLOW_PORT_OVERRIDE:-5000}:5000'
    environment:
      TZ: ${TZ:-UTC}
      MLFLOW_BACKEND_STORE_URI: postgresql://${POSTGRES_USER:-mlflow}:${POSTGRES_PASSWORD:-mlflow}@postgres:5432/${POSTGRES_DB:-mlflow}
      MLFLOW_ARTIFACT_ROOT: s3://${MINIO_BUCKET:-mlflow}/
      MLFLOW_S3_ENDPOINT_URL: http://minio:9000
      AWS_ACCESS_KEY_ID: ${MINIO_ROOT_USER:-minio}
      AWS_SECRET_ACCESS_KEY: ${MINIO_ROOT_PASSWORD:-minio123}
    command:
      - mlflow
      - server
      - --host
      - 0.0.0.0
      - --port
      - '5000'
      - --backend-store-uri
      - postgresql://${POSTGRES_USER:-mlflow}:${POSTGRES_PASSWORD:-mlflow}@postgres:5432/${POSTGRES_DB:-mlflow}
      - --default-artifact-root
      - s3://${MINIO_BUCKET:-mlflow}/
    deploy:
      resources:
        limits:
          cpus: ${MLFLOW_CPU_LIMIT:-2.0}
          memory: ${MLFLOW_MEMORY_LIMIT:-2G}
        reservations:
          cpus: ${MLFLOW_CPU_RESERVATION:-0.1}
          memory: ${MLFLOW_MEMORY_RESERVATION:-1G}
    healthcheck:
      test: [CMD, wget, --no-verbose, --tries=1, --spider, 'http://localhost:5000/health']
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 30s

volumes:
  postgres_data:
  minio_data:
