MLflow Tracking Server
MLflow for ML experiment tracking with PostgreSQL and MinIO.
Overview
MLflow is an open-source platform developed by Databricks that addresses the complete machine learning lifecycle, from experimentation to production deployment. It provides essential MLOps capabilities including experiment tracking, model versioning, artifact storage, and model registry management. The platform has become increasingly popular since its 2018 release as organizations struggle to manage the complexity of ML workflows, reproducibility challenges, and collaboration across data science teams.
This stack combines MLflow's tracking server with PostgreSQL as the backend store and MinIO for artifact storage, creating a production-grade ML experiment management system. PostgreSQL handles all metadata storage including experiment parameters, metrics, and run information with ACID compliance and robust querying capabilities. MinIO provides S3-compatible object storage for model artifacts, datasets, and other files, offering high performance and data protection through erasure coding. This architecture separates concerns effectively - PostgreSQL excels at structured metadata while MinIO handles large binary artifacts.
Data science teams, ML engineers, and organizations implementing MLOps practices should consider this stack when they need centralized experiment tracking with proper data persistence. Unlike cloud-hosted solutions like Weights & Biases, this self-hosted approach provides complete control over sensitive ML data and eliminates recurring costs. The combination is particularly valuable for teams already familiar with PostgreSQL operations or those requiring compliance with data residency requirements, while MinIO's S3 compatibility ensures easy migration paths to cloud storage when needed.
Key Features
- Centralized experiment tracking with parameter, metric, and artifact logging across multiple ML frameworks
- Model registry with versioning, stage transitions, and lifecycle management for production deployments
- S3-compatible artifact storage through MinIO with high-performance throughput and data protection
- PostgreSQL backend providing ACID-compliant metadata storage with advanced querying capabilities
- Multi-framework support including scikit-learn, TensorFlow, PyTorch, XGBoost, and custom models
- Web UI for experiment comparison, visualization, and collaborative model review processes
- RESTful API enabling programmatic access to experiments, runs, and model registry operations
- Artifact versioning and lineage tracking for reproducible ML workflows and audit trails
Common Use Cases
- 1Data science teams needing centralized experiment tracking across multiple ML projects and researchers
- 2MLOps implementation for organizations transitioning from ad-hoc ML workflows to structured processes
- 3Model comparison and hyperparameter optimization workflows with historical performance analysis
- 4Regulatory compliance scenarios requiring on-premises ML artifact storage and audit trails
- 5Multi-team ML organizations needing shared model registry with controlled deployment stages
- 6Academic research institutions requiring cost-effective ML experiment management without cloud vendor lock-in
- 7Enterprises with data residency requirements preventing use of cloud-hosted ML tracking platforms
Prerequisites
- Minimum 2GB RAM available (1GB for MLflow/PostgreSQL, 512MB for MinIO operations)
- Docker and Docker Compose installed with ports 5000, 9000, and 9001 available
- Basic understanding of MLflow concepts including experiments, runs, and artifact storage
- Python environment with mlflow package installed for client-side experiment logging
- Network access between ML training environments and the MLflow tracking server
- Understanding of S3-compatible storage concepts for artifact management configuration
For development & testing. Review security settings, change default credentials, and test thoroughly before production use. See Terms
docker-compose.yml
docker-compose.yml
1services: 2 postgres: 3 image: postgres:16-alpine4 container_name: mlflow-postgres5 restart: unless-stopped6 environment: 7 POSTGRES_USER: ${POSTGRES_USER:-mlflow}8 POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-mlflow}9 POSTGRES_DB: ${POSTGRES_DB:-mlflow}10 volumes: 11 - postgres_data:/var/lib/postgresql/data12 networks: 13 - mlflow-network1415 minio: 16 image: minio/minio:latest17 container_name: mlflow-minio18 restart: unless-stopped19 ports: 20 - "${MINIO_PORT:-9000}:9000"21 - "${MINIO_CONSOLE_PORT:-9001}:9001"22 environment: 23 MINIO_ROOT_USER: ${MINIO_USER:-minioadmin}24 MINIO_ROOT_PASSWORD: ${MINIO_PASSWORD:-minioadmin}25 command: server /data --console-address ":9001"26 volumes: 27 - minio_data:/data28 networks: 29 - mlflow-network3031 mlflow: 32 image: ghcr.io/mlflow/mlflow:latest33 container_name: mlflow34 restart: unless-stopped35 ports: 36 - "${MLFLOW_PORT:-5000}:5000"37 environment: 38 MLFLOW_S3_ENDPOINT_URL: http://minio:900039 AWS_ACCESS_KEY_ID: ${MINIO_USER:-minioadmin}40 AWS_SECRET_ACCESS_KEY: ${MINIO_PASSWORD:-minioadmin}41 command: >42 mlflow server43 --backend-store-uri postgresql: //${POSTGRES_USER:-mlflow}:${POSTGRES_PASSWORD:-mlflow}@postgres:5432/${POSTGRES_DB:-mlflow}44 --default-artifact-root s3: //mlflow/45 --host 0.0.0.046 depends_on: 47 - postgres48 - minio49 networks: 50 - mlflow-network5152volumes: 53 postgres_data: 54 minio_data: 5556networks: 57 mlflow-network: 58 driver: bridge.env Template
.env
1# MLflow2MLFLOW_PORT=50003POSTGRES_USER=mlflow4POSTGRES_PASSWORD=mlflow5POSTGRES_DB=mlflow6MINIO_PORT=90007MINIO_CONSOLE_PORT=90018MINIO_USER=minioadmin9MINIO_PASSWORD=minioadminUsage Notes
- 1Docs: https://mlflow.org/docs/latest/
- 2MLflow UI at http://localhost:5000 - experiments, runs, model registry
- 3MinIO Console at http://localhost:9001 - create 'mlflow' bucket first
- 4Python: mlflow.set_tracking_uri('http://localhost:5000'), mlflow.log_*
- 5Set MLFLOW_S3_ENDPOINT_URL in client for artifact storage
- 6Model registry: mlflow.register_model(), stage transitions
Individual Services(3 services)
Copy individual services to mix and match with your existing compose files.
postgres
postgres:
image: postgres:16-alpine
container_name: mlflow-postgres
restart: unless-stopped
environment:
POSTGRES_USER: ${POSTGRES_USER:-mlflow}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-mlflow}
POSTGRES_DB: ${POSTGRES_DB:-mlflow}
volumes:
- postgres_data:/var/lib/postgresql/data
networks:
- mlflow-network
minio
minio:
image: minio/minio:latest
container_name: mlflow-minio
restart: unless-stopped
ports:
- ${MINIO_PORT:-9000}:9000
- ${MINIO_CONSOLE_PORT:-9001}:9001
environment:
MINIO_ROOT_USER: ${MINIO_USER:-minioadmin}
MINIO_ROOT_PASSWORD: ${MINIO_PASSWORD:-minioadmin}
command: server /data --console-address ":9001"
volumes:
- minio_data:/data
networks:
- mlflow-network
mlflow
mlflow:
image: ghcr.io/mlflow/mlflow:latest
container_name: mlflow
restart: unless-stopped
ports:
- ${MLFLOW_PORT:-5000}:5000
environment:
MLFLOW_S3_ENDPOINT_URL: http://minio:9000
AWS_ACCESS_KEY_ID: ${MINIO_USER:-minioadmin}
AWS_SECRET_ACCESS_KEY: ${MINIO_PASSWORD:-minioadmin}
command: |
mlflow server --backend-store-uri postgresql://${POSTGRES_USER:-mlflow}:${POSTGRES_PASSWORD:-mlflow}@postgres:5432/${POSTGRES_DB:-mlflow} --default-artifact-root s3://mlflow/ --host 0.0.0.0
depends_on:
- postgres
- minio
networks:
- mlflow-network
Quick Start
terminal
1# 1. Create the compose file2cat > docker-compose.yml << 'EOF'3services:4 postgres:5 image: postgres:16-alpine6 container_name: mlflow-postgres7 restart: unless-stopped8 environment:9 POSTGRES_USER: ${POSTGRES_USER:-mlflow}10 POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-mlflow}11 POSTGRES_DB: ${POSTGRES_DB:-mlflow}12 volumes:13 - postgres_data:/var/lib/postgresql/data14 networks:15 - mlflow-network1617 minio:18 image: minio/minio:latest19 container_name: mlflow-minio20 restart: unless-stopped21 ports:22 - "${MINIO_PORT:-9000}:9000"23 - "${MINIO_CONSOLE_PORT:-9001}:9001"24 environment:25 MINIO_ROOT_USER: ${MINIO_USER:-minioadmin}26 MINIO_ROOT_PASSWORD: ${MINIO_PASSWORD:-minioadmin}27 command: server /data --console-address ":9001"28 volumes:29 - minio_data:/data30 networks:31 - mlflow-network3233 mlflow:34 image: ghcr.io/mlflow/mlflow:latest35 container_name: mlflow36 restart: unless-stopped37 ports:38 - "${MLFLOW_PORT:-5000}:5000"39 environment:40 MLFLOW_S3_ENDPOINT_URL: http://minio:900041 AWS_ACCESS_KEY_ID: ${MINIO_USER:-minioadmin}42 AWS_SECRET_ACCESS_KEY: ${MINIO_PASSWORD:-minioadmin}43 command: >44 mlflow server45 --backend-store-uri postgresql://${POSTGRES_USER:-mlflow}:${POSTGRES_PASSWORD:-mlflow}@postgres:5432/${POSTGRES_DB:-mlflow}46 --default-artifact-root s3://mlflow/47 --host 0.0.0.048 depends_on:49 - postgres50 - minio51 networks:52 - mlflow-network5354volumes:55 postgres_data:56 minio_data:5758networks:59 mlflow-network:60 driver: bridge61EOF6263# 2. Create the .env file64cat > .env << 'EOF'65# MLflow66MLFLOW_PORT=500067POSTGRES_USER=mlflow68POSTGRES_PASSWORD=mlflow69POSTGRES_DB=mlflow70MINIO_PORT=900071MINIO_CONSOLE_PORT=900172MINIO_USER=minioadmin73MINIO_PASSWORD=minioadmin74EOF7576# 3. Start the services77docker compose up -d7879# 4. View logs80docker compose logs -fOne-Liner
Run this command to download and set up the recipe in one step:
terminal
1curl -fsSL https://docker.recipes/api/recipes/mlflow-tracking-server/run | bashTroubleshooting
- MLflow server fails to start with database connection error: Ensure PostgreSQL container is healthy and POSTGRES_PASSWORD matches between services
- Artifacts not uploading with S3 connection timeout: Create 'mlflow' bucket in MinIO console at localhost:9001 and verify MINIO_USER credentials
- Experiment logging fails with 'Connection refused': Set mlflow.set_tracking_uri('http://localhost:5000') and ensure MLflow server port is accessible
- MinIO returns 'Access Denied' for artifact storage: Verify AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY environment variables match MinIO root credentials
- PostgreSQL data loss after container restart: Check that postgres_data volume is properly mounted and has sufficient disk space
- MLflow UI shows experiments but artifacts missing: Confirm MLFLOW_S3_ENDPOINT_URL is set to http://minio:9000 in client environment
Community Notes
Loading...
Loading notes...
Download Recipe Kit
Get all files in a ready-to-deploy package
Includes docker-compose.yml, .env template, README, and license
Components
mlflowpostgresqlminio
Tags
#mlflow#ml-ops#tracking#experiments#models
Category
AI & Machine LearningAd Space
Shortcuts: C CopyF FavoriteD Download