Skip to content

Docker

This guide covers deploying a Haute pipeline as a Docker container - a self-contained package that can run anywhere. When you merge to main, CI builds the container image and pushes it to a registry. Your IT team (or a cloud platform like AWS ECS or Azure Container Apps) runs it from there.

What is Docker?

Docker is a tool that packages your application and everything it needs (Python, libraries, model files) into a single container - like a shipping container for software. Anyone with Docker installed can run it, regardless of what's on their machine. You don't need to understand Docker to use this target - Haute and CI handle everything.

You don't need Docker on your laptop

Docker runs on the CI runner, not your machine. You never need to install Docker, build images, or run containers yourself. You just merge to main and CI does the rest. Your IT team takes the built image and deploys it to their infrastructure.

If your organisation uses Databricks, the Databricks target is simpler and doesn't involve containers at all.

When should I choose this target?

Choose Docker if your company doesn't use Databricks and your IT team has asked you for a container image, or if they've said they'll handle the hosting and just need a package from you. This is also the right choice if your IT team uses Kubernetes, Docker Compose, or any other container platform you haven't heard of - you don't need to know what those are.

This target involves your IT team

As an analyst, your role is to configure haute.toml and merge to main. CI builds and pushes the Docker image automatically. Your IT team handles everything else - the registry, the hosting, the infrastructure. The sections below are split: Steps 1-3 are for you, and the "For your IT team" section at the bottom is reference material for IT.


How it works

  1. You edit your pipeline locally and preview with haute serve
  2. You merge to main - CI automatically builds a Docker image containing your pipeline and pushes it to a container registry
  3. Your IT team (or an automated platform) runs the image as a service, exposing the API

You never touch Docker. CI handles the build and push; IT handles the infrastructure.


Prerequisites

Before you start, you need:

  • Python 3.11+ installed on your machine
  • Haute installed (uv add haute - see Installing Haute)
  • A container registry - this is an online storage service for Docker images (like a shared drive for containers). Ask your IT team which registry your company uses - they'll give you the registry URL and credentials

If you haven't initialised your project yet, open your VS Code terminal and run:

haute init --target container --ci github

Your team may have already done this

If you cloned an existing project that already has a haute.toml file, skip this step - it's already initialised.


Step 1: Add registry credentials to CI

This step is usually done by IT

Your IT team will know the registry URL and credentials. Ask them to add these as CI secrets, or give them the .env.example file from your project.

CI needs credentials to push the Docker image to your registry. Add these as encrypted secrets in your CI provider:

Secret name Value
DOCKER_USERNAME Your registry username
DOCKER_PASSWORD Your registry password or access token

How to add them depends on your CI provider - see GitHub Actions, GitLab, or Azure DevOps.


Step 2: Configure haute.toml

Here's what the container section of your haute.toml looks like:

[project]
name = "motor-pricing"
pipeline = "main.py"

[deploy]
target = "container"
model_name = "motor-pricing"

[deploy.container]
registry = ""
port = 8080
base_image = "python:3.11-slim"

[test_quotes]
dir = "tests/quotes"

What each setting means

Setting What it does Example
target Tells Haute to build a Docker container "container"
model_name Used as the Docker image name "motor-pricing"
registry Where to push the image. Leave empty for local-only. "ghcr.io/myorg" or ""
port The port the API server listens on inside the container (like an extension number on a phone system) 8080
base_image The base Docker image to build from "python:3.11-slim"

The registry value is the address your IT team gave you for where Docker images are stored. If you don't know it, ask them: "What's our container registry URL?" They'll give you something like ghcr.io/yourorg or myregistry.azurecr.io. Put that value in haute.toml.


Step 3: Deploy by merging to main

You don't run any deploy command. When you merge to main, CI automatically:

  1. Validates your pipeline and scores test quotes
  2. Generates an API app that wraps your pipeline (with two web addresses: /quote for scoring and /health for status checks)
  3. Generates a Dockerfile (a recipe that tells Docker how to build the container)
  4. Builds the Docker image
  5. Pushes the image to your registry

Once the image is in the registry, your IT team (or an automated platform) can pull and run it.

What does success look like?

After a successful merge to main, you should see:

  1. In your CI provider - all pipeline steps show green ✓ (validation, build, push)
  2. In the CI logs - a message like Pushed motor-pricing:a1b2c3d to ghcr.io/yourorg/motor-pricing
  3. From your IT team - they'll confirm the container is running and give you the endpoint URL to test

If CI is green and your IT team says the service is up, your pipeline is live.


Step 4: Test the deployed API

Once your IT team has the container running, you can test it with Python:

import requests

# Replace with the actual URL your IT team gives you
url = "http://<your-endpoint>:8080"

# Score a test quote
response = requests.post(
    f"{url}/quote",
    json=[{"IDpol": 99001, "VehPower": 7, "DrivAge": 42, "Area": "C", "VehBrand": "B12"}],
)
print(response.json())

# Check the service is alive
health = requests.get(f"{url}/health")
print(health.json())  # {"status": "ok"}

For your IT team

As an analyst, you can stop reading here - your job is done after Step 4 above. The sections below are reference material for whoever manages the container registry and hosting infrastructure.

What Haute generates (click to expand)

When Haute deploys, it creates a .haute_build/ directory containing:

File Purpose
app.py API application (built with FastAPI) that wraps the scoring pipeline
Dockerfile Instructions for building the Docker image
deploy_manifest.json Metadata about what was deployed (version, schemas, artifacts)
artifacts/ Copies of model files

These are generated fresh on every deploy.

API contract (click to expand)

The generated container exposes two endpoints:

Endpoint Method Purpose
/quote POST Send quote data (JSON array), receive premium results
/health GET Returns {"status": "ok"} - used by infrastructure to check the service is alive

The /quote endpoint accepts a JSON array of quote objects and returns the pipeline output as JSON. No MLflow, no pandas - just JSON in, JSON out.

Registry options (click to expand)
Registry registry value in haute.toml Credentials needed
Docker Hub docker.io/yourname Docker Hub username + access token
GitHub Container Registry ghcr.io/yourorg GitHub username + personal access token
AWS ECR 123456789012.dkr.ecr.eu-west-1.amazonaws.com AWS credentials
Azure Container Registry myregistry.azurecr.io Azure service principal
Local only "" (empty) None needed
Handing off the image (click to expand)

The Docker image is pushed to the registry configured in haute.toml. You can also export it as a .tar file:

docker save motor-pricing:a1b2c3d > motor-pricing.tar

The image can run on any platform that supports Docker containers - Kubernetes, Docker Compose, AWS ECS, Azure Container Apps, or others. It requires:

  • POST /quote on the configured port (default 8080)
  • GET /health on the same port
  • No environment variables required at runtime

Troubleshooting

CI fails with "authentication required" on push

The registry credentials in your CI secrets are missing or incorrect. Check that DOCKER_USERNAME and DOCKER_PASSWORD are set correctly in your CI provider.

CI fails during image build

Check the CI logs for the build step. Common causes:

  • Missing Python dependencies - check your pyproject.toml includes all required packages
  • Model file not found - ensure all model files referenced in your pipeline are committed to the repository

Container crashes on startup (reported by IT)

Ask your IT team for the container logs. Common causes:

  • Missing dependencies inside the image
  • Model files not found - ensure they're committed and referenced correctly in your pipeline

API returns errors

If the container is running but /quote returns errors, the pipeline is likely failing at runtime. Check the container logs for Python tracebacks. The most common cause is a schema mismatch between the request JSON and what your pipeline expects.