Contents

Chapter 1

MLflow Setup Guide

This guide takes you from "nothing installed" to a working MLflow tracking

server with a Postgres metadata store and an S3-compatible artifact store, then

shows how to point the kit at it. Read it once end-to-end; afterwards the

Model Registry Workflow guide covers promotion.

1. The three pieces of an MLflow deployment

Every MLflow setup is made of three independent pieces. Getting them straight

saves hours of confusion:

PieceWhat it storesThis kit uses
Tracking serverThe REST API and Web UImlflow server on port 5000
Backend storeRuns, params, metrics, registry metadataPostgreSQL
Artifact storeModels, plots, datasets, large filesMinIO (S3-compatible)

A common beginner setup collapses all three into the local filesystem

(file:./mlruns). That is fine for a laptop spike but it cannot be shared, has

no model registry over HTTP, and corrupts easily under concurrent writes. The

bundled docker/docker-compose.yml gives you the real, shareable topology with

one command.

2. Fastest path: the bundled Docker stack

bash
# From the product root
docker compose -f docker/docker-compose.yml up -d

# Watch the tracking server come up (first boot pip-installs deps)
docker compose -f docker/docker-compose.yml logs -f mlflow

When the logs show Listening at: http://0.0.0.0:5000, open:

  • MLflow UI -> http://localhost:5000
  • MinIO console -> http://localhost:9001 (login minioadmin / minioadmin)

The stack wires everything together for you:

  • Postgres is the --backend-store-uri.
  • MinIO is the --artifacts-destination (bucket s3://mlflow).
  • The server runs with --serve-artifacts, so **clients never need MinIO

credentials** -- they upload/download artifacts *through* the tracking server

using the mlflow-artifacts:/ scheme. This is the recommended modern pattern

and the reason your training code only needs one URL.

Tear it down (keeping data in named volumes) with:

bash
docker compose -f docker/docker-compose.yml down
# add -v to also delete the postgres_data / minio_data volumes

3. Pointing the kit at the server

The kit centralises configuration in mlflow_starter.config.MLflowConfig. The

idiomatic flow is "read environment, then apply":

python
from mlflow_starter import MLflowConfig, configure

config = MLflowConfig.from_env()      # reads MLFLOW_TRACKING_URI, tags, etc.
config.experiment_name = "churn-modeling"
configure(config)                     # exports env + sets the MLflow client URIs

Set the environment once in your shell (or a .env consumed by your process

manager):

bash
export MLFLOW_TRACKING_URI=http://localhost:5000
export MLFLOW_EXPERIMENT_NAME=churn-modeling
export MLFLOW_DEFAULT_TAGS='{"team": "ml-platform", "project": "churn"}'

MLFLOW_DEFAULT_TAGS is a JSON object string; the kit parses it and applies

those tags to every run opened through experiment_run.

Server-less fallback

No server running? Use a local file store. The example scripts already do this

automatically, but you can force it explicitly:

python
config = MLflowConfig(tracking_uri="file:./mlruns", experiment_name="quick-test")
configure(config)

Everything in tracking.py works against a file store except the *registry*

features, which require a database-backed server (Postgres here). That is the

single biggest reason to run the Docker stack.

4. Using a real cloud artifact store

MinIO speaks the S3 API, so moving to AWS S3, GCS (via the S3 interop), or any

S3-compatible object store is a configuration change, not a code change. For

real AWS S3 you simply drop the custom endpoint:

python
config = MLflowConfig(
    tracking_uri="https://internal.docs.example.com",
    artifact_location="s3://acme-ml-artifacts/mlflow/",
    s3_endpoint_url=None,          # None => default AWS endpoints
)
config.apply()

MLflowConfig.apply() only exports credentials that are actually set, so it

will never overwrite real IAM-role credentials with empty values. On AWS,

prefer an instance/role profile over static keys and leave

aws_access_key_id / aws_secret_access_key unset.

5. Verifying the connection

A 20-second smoke test that proves the whole chain (server + DB + artifacts) is

healthy:

python
import mlflow
from mlflow_starter import MLflowConfig, configure, experiment_run, log_metrics

configure(MLflowConfig.from_env())
with experiment_run("smoke-test") as run:
    log_metrics({"answer": 42})
    mlflow.log_text("hello from the smoke test", "notes.txt")
    print("run id:", run.info.run_id)

If this run appears in the UI and notes.txt is downloadable from its

Artifacts tab, your backend store and artifact store are both wired correctly.

If the run shows but the artifact 404s, your artifact store is misconfigured

(see Troubleshooting).

6. Troubleshooting

Connection refused to localhost:5000. The server container is still

pip-installing on first boot. Watch docker compose logs -f mlflow and wait for

the Listening at line.

Runs appear but artifacts fail to upload / 404. You are almost certainly

mixing the proxied-artifact and direct-S3 patterns. With this kit's stack the

server runs --serve-artifacts, so clients must use the tracking URL only --

do not also set MLFLOW_S3_ENDPOINT_URL in your *client* environment, or

the client will try to reach MinIO directly at a hostname it cannot resolve.

psycopg2 / database errors. The Postgres container failed its healthcheck

before MLflow started. Run docker compose ps and confirm postgres is

healthy; if it is restarting, you likely have a stale postgres_data volume

from an older Postgres major version -- remove it with down -v.

Registry calls raise RestException: ... not supported. You are pointed at

a file: store. Stage transitions and the model registry require the

database-backed server. Switch MLFLOW_TRACKING_URI to http://localhost:5000.

Stale model in serving. Loading models://Production always resolves

the *current* Production version. If a server keeps an old model, it cached it

at startup -- restart the scoring container after a promotion, or use aliases

plus a redeploy (see the registry workflow guide).

7. Production hardening checklist

Before this leaves your laptop:

1. Replace minioadmin / mlflow passwords; move them into a secrets manager.

2. Put the tracking server behind TLS and an auth proxy (MLflow has no built-in

auth in the open-source server).

3. Pin every image tag (postgres:16.3, a dated minio release) instead of

latest for reproducible rebuilds.

4. Back up the Postgres database -- it is the source of truth for your entire

experiment and model history.

5. Bake the MLflow server dependencies into a custom image so restarts do not

re-run pip install.

Chapter 2
🔒 Available in full product

Model Registry Workflow

Chapter 3
🔒 Available in full product

MLflow Setup Guide

Chapter 4
🔒 Available in full product

Model Registry Workflow

You’ve reached the end of the free preview

Get the full MLflow Starter Kit and unlock everything.

All Chapters

Get the complete guide with every chapter unlocked, including code samples, diagrams, and best practices.

Full Tool Suite

Access all interactive tools with complete data, all workload profiles, and the full scenario library.

Source Files

Downloadable source code, configuration files, and working examples from every chapter.

Lifetime Updates

Free updates for life. Every new chapter, tool, and improvement included.

Buy Now — $39 →
📦 Free sample included — download another copy or visit the store for the full product.
MLflow Starter Kit v1.0.0 — Free Preview