ML Training & Serving Stack
Complete ML pipeline with MLflow tracking, MinIO artifact storage, and Seldon serving
Overview
MLflow is an open-source platform developed by Databricks that manages the complete machine learning lifecycle, from experimentation and tracking to model deployment and monitoring. Originally created to address the fragmentation in ML tooling, MLflow provides a unified interface for experiment tracking, model versioning, and deployment across multiple frameworks like TensorFlow, PyTorch, and scikit-learn. This stack combines MLflow's comprehensive ML lifecycle management with MinIO's S3-compatible object storage for artifacts and PostgreSQL's robust relational database for metadata storage. The integration creates a complete MLOps pipeline where MinIO handles large model files and datasets while PostgreSQL stores experiment parameters, metrics, and model registry information. MLflow orchestrates the entire workflow, providing a centralized hub for data scientists and ML engineers to track experiments, compare models, and deploy the best performers. This configuration is ideal for ML teams transitioning from notebook-driven development to production-ready MLOps workflows, startups building their first ML infrastructure, and organizations requiring complete control over their ML artifacts and metadata without cloud vendor lock-in.
Key Features
- Experiment tracking with automatic parameter, metric, and artifact logging
- Model registry for versioning, staging, and production model management
- S3-compatible artifact storage via MinIO for models, datasets, and experiment outputs
- PostgreSQL backend for reliable metadata storage and complex experiment querying
- Multi-framework support including TensorFlow, PyTorch, scikit-learn, and XGBoost
- Jupyter notebook integration with pre-configured MLflow tracking environment
- Web-based UI for experiment comparison, model visualization, and artifact browsing
- RESTful API for programmatic access to experiments, models, and deployment
Common Use Cases
- 1ML research teams tracking hyperparameter tuning experiments across multiple algorithms
- 2Data science departments comparing model performance across different feature sets
- 3Startups building their first production ML pipeline without cloud dependencies
- 4Organizations migrating from cloud-based ML platforms to self-hosted infrastructure
- 5Educational institutions teaching MLOps and experiment management practices
- 6Companies requiring audit trails and governance for regulatory compliance
- 7Development teams implementing A/B testing for model performance evaluation
Prerequisites
- Minimum 4GB RAM (MLflow: 1GB, PostgreSQL: 1GB, MinIO: 2GB recommended)
- Ports 5000, 8888, 9000, and 9001 available on host system
- Docker and Docker Compose installed with volume mounting capabilities
- Basic understanding of Python ML libraries and experiment tracking concepts
- Familiarity with S3-style object storage APIs for advanced artifact management
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 mlflow: 3 image: ghcr.io/mlflow/mlflow:latest4 container_name: mlflow5 restart: unless-stopped6 ports: 7 - "${MLFLOW_PORT:-5000}:5000"8 command: mlflow server --backend-store-uri postgresql://${DB_USER}:${DB_PASSWORD}@mlflow-db:5432/mlflow --default-artifact-root s3://mlflow/ --host 0.0.0.09 environment: 10 - MLFLOW_S3_ENDPOINT_URL=http://minio:900011 - AWS_ACCESS_KEY_ID=${MINIO_ACCESS_KEY}12 - AWS_SECRET_ACCESS_KEY=${MINIO_SECRET_KEY}13 depends_on: 14 - mlflow-db15 - minio1617 mlflow-db: 18 image: postgres:15-alpine19 container_name: mlflow-db20 restart: unless-stopped21 environment: 22 - POSTGRES_USER=${DB_USER}23 - POSTGRES_PASSWORD=${DB_PASSWORD}24 - POSTGRES_DB=mlflow25 volumes: 26 - mlflow_db_data:/var/lib/postgresql/data2728 minio: 29 image: minio/minio:latest30 container_name: mlflow-minio31 restart: unless-stopped32 ports: 33 - "${MINIO_PORT:-9000}:9000"34 - "${MINIO_CONSOLE:-9001}:9001"35 environment: 36 - MINIO_ROOT_USER=${MINIO_ACCESS_KEY}37 - MINIO_ROOT_PASSWORD=${MINIO_SECRET_KEY}38 volumes: 39 - minio_data:/data40 command: server /data --console-address ":9001"4142 minio-init: 43 image: minio/mc:latest44 container_name: minio-init45 depends_on: 46 - minio47 entrypoint: >48 /bin/sh -c "49 sleep 5;50 mc alias set myminio http: //minio:9000 ${MINIO_ACCESS_KEY} ${MINIO_SECRET_KEY};51 mc mb myminio/mlflow --ignore-existing;52 exit 0;53 "5455 jupyter: 56 image: jupyter/scipy-notebook:latest57 container_name: jupyter58 restart: unless-stopped59 ports: 60 - "${JUPYTER_PORT:-8888}:8888"61 environment: 62 - MLFLOW_TRACKING_URI=http://mlflow:500063 - MLFLOW_S3_ENDPOINT_URL=http://minio:900064 - AWS_ACCESS_KEY_ID=${MINIO_ACCESS_KEY}65 - AWS_SECRET_ACCESS_KEY=${MINIO_SECRET_KEY}66 volumes: 67 - ./notebooks:/home/jovyan/work68 depends_on: 69 - mlflow7071volumes: 72 mlflow_db_data: 73 minio_data: .env Template
.env
1# ML Training & Serving Stack2MLFLOW_PORT=50003MINIO_PORT=90004MINIO_CONSOLE=90015JUPYTER_PORT=888867# Database8DB_USER=mlflow9DB_PASSWORD=mlflow_password1011# MinIO12MINIO_ACCESS_KEY=minioadmin13MINIO_SECRET_KEY=minioadminUsage Notes
- 1MLflow UI at http://localhost:5000
- 2MinIO Console at http://localhost:9001
- 3Jupyter Lab at http://localhost:8888
- 4Check Jupyter logs for access token
- 5MLflow tracks experiments, MinIO stores artifacts
- 6Use mlflow.log_params(), mlflow.log_metrics() in code
Individual Services(5 services)
Copy individual services to mix and match with your existing compose files.
mlflow
mlflow:
image: ghcr.io/mlflow/mlflow:latest
container_name: mlflow
restart: unless-stopped
ports:
- ${MLFLOW_PORT:-5000}:5000
command: mlflow server --backend-store-uri postgresql://${DB_USER}:${DB_PASSWORD}@mlflow-db:5432/mlflow --default-artifact-root s3://mlflow/ --host 0.0.0.0
environment:
- MLFLOW_S3_ENDPOINT_URL=http://minio:9000
- AWS_ACCESS_KEY_ID=${MINIO_ACCESS_KEY}
- AWS_SECRET_ACCESS_KEY=${MINIO_SECRET_KEY}
depends_on:
- mlflow-db
- minio
mlflow-db
mlflow-db:
image: postgres:15-alpine
container_name: mlflow-db
restart: unless-stopped
environment:
- POSTGRES_USER=${DB_USER}
- POSTGRES_PASSWORD=${DB_PASSWORD}
- POSTGRES_DB=mlflow
volumes:
- mlflow_db_data:/var/lib/postgresql/data
minio
minio:
image: minio/minio:latest
container_name: mlflow-minio
restart: unless-stopped
ports:
- ${MINIO_PORT:-9000}:9000
- ${MINIO_CONSOLE:-9001}:9001
environment:
- MINIO_ROOT_USER=${MINIO_ACCESS_KEY}
- MINIO_ROOT_PASSWORD=${MINIO_SECRET_KEY}
volumes:
- minio_data:/data
command: server /data --console-address ":9001"
minio-init
minio-init:
image: minio/mc:latest
container_name: minio-init
depends_on:
- minio
entrypoint: |
/bin/sh -c " sleep 5; mc alias set myminio http://minio:9000 ${MINIO_ACCESS_KEY} ${MINIO_SECRET_KEY}; mc mb myminio/mlflow --ignore-existing; exit 0; "
jupyter
jupyter:
image: jupyter/scipy-notebook:latest
container_name: jupyter
restart: unless-stopped
ports:
- ${JUPYTER_PORT:-8888}:8888
environment:
- MLFLOW_TRACKING_URI=http://mlflow:5000
- MLFLOW_S3_ENDPOINT_URL=http://minio:9000
- AWS_ACCESS_KEY_ID=${MINIO_ACCESS_KEY}
- AWS_SECRET_ACCESS_KEY=${MINIO_SECRET_KEY}
volumes:
- ./notebooks:/home/jovyan/work
depends_on:
- mlflow
Quick Start
terminal
1# 1. Create the compose file2cat > docker-compose.yml << 'EOF'3services:4 mlflow:5 image: ghcr.io/mlflow/mlflow:latest6 container_name: mlflow7 restart: unless-stopped8 ports:9 - "${MLFLOW_PORT:-5000}:5000"10 command: mlflow server --backend-store-uri postgresql://${DB_USER}:${DB_PASSWORD}@mlflow-db:5432/mlflow --default-artifact-root s3://mlflow/ --host 0.0.0.011 environment:12 - MLFLOW_S3_ENDPOINT_URL=http://minio:900013 - AWS_ACCESS_KEY_ID=${MINIO_ACCESS_KEY}14 - AWS_SECRET_ACCESS_KEY=${MINIO_SECRET_KEY}15 depends_on:16 - mlflow-db17 - minio1819 mlflow-db:20 image: postgres:15-alpine21 container_name: mlflow-db22 restart: unless-stopped23 environment:24 - POSTGRES_USER=${DB_USER}25 - POSTGRES_PASSWORD=${DB_PASSWORD}26 - POSTGRES_DB=mlflow27 volumes:28 - mlflow_db_data:/var/lib/postgresql/data2930 minio:31 image: minio/minio:latest32 container_name: mlflow-minio33 restart: unless-stopped34 ports:35 - "${MINIO_PORT:-9000}:9000"36 - "${MINIO_CONSOLE:-9001}:9001"37 environment:38 - MINIO_ROOT_USER=${MINIO_ACCESS_KEY}39 - MINIO_ROOT_PASSWORD=${MINIO_SECRET_KEY}40 volumes:41 - minio_data:/data42 command: server /data --console-address ":9001"4344 minio-init:45 image: minio/mc:latest46 container_name: minio-init47 depends_on:48 - minio49 entrypoint: >50 /bin/sh -c "51 sleep 5;52 mc alias set myminio http://minio:9000 ${MINIO_ACCESS_KEY} ${MINIO_SECRET_KEY};53 mc mb myminio/mlflow --ignore-existing;54 exit 0;55 "5657 jupyter:58 image: jupyter/scipy-notebook:latest59 container_name: jupyter60 restart: unless-stopped61 ports:62 - "${JUPYTER_PORT:-8888}:8888"63 environment:64 - MLFLOW_TRACKING_URI=http://mlflow:500065 - MLFLOW_S3_ENDPOINT_URL=http://minio:900066 - AWS_ACCESS_KEY_ID=${MINIO_ACCESS_KEY}67 - AWS_SECRET_ACCESS_KEY=${MINIO_SECRET_KEY}68 volumes:69 - ./notebooks:/home/jovyan/work70 depends_on:71 - mlflow7273volumes:74 mlflow_db_data:75 minio_data:76EOF7778# 2. Create the .env file79cat > .env << 'EOF'80# ML Training & Serving Stack81MLFLOW_PORT=500082MINIO_PORT=900083MINIO_CONSOLE=900184JUPYTER_PORT=88888586# Database87DB_USER=mlflow88DB_PASSWORD=mlflow_password8990# MinIO91MINIO_ACCESS_KEY=minioadmin92MINIO_SECRET_KEY=minioadmin93EOF9495# 3. Start the services96docker compose up -d9798# 4. View logs99docker 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/ml-training-serving-stack/run | bashTroubleshooting
- MLflow UI shows 'Cannot connect to backend store': Verify PostgreSQL container is running and DB_USER/DB_PASSWORD environment variables match
- Artifact storage fails with S3 errors: Check MINIO_ACCESS_KEY and MINIO_SECRET_KEY are set correctly and minio-init container completed successfully
- Jupyter notebook cannot connect to MLflow: Ensure MLFLOW_TRACKING_URI points to http://mlflow:5000 and containers are on the same Docker network
- MinIO console login fails: Use MINIO_ACCESS_KEY as username and MINIO_SECRET_KEY as password, not root/admin defaults
- Experiment logging slow or timing out: Increase PostgreSQL memory allocation and check disk space for both database and MinIO volumes
- Model artifacts not appearing in MLflow UI: Verify MinIO bucket 'mlflow' exists and MLflow has correct S3 endpoint configuration
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
mlflowminiopostgresseldon-core
Tags
#mlflow#mlops#training#serving#minio#machine-learning
Category
AI & Machine LearningAd Space
Shortcuts: C CopyF FavoriteD Download