30 Days of AIDay 17 of 30 · Week 3: Infrastructure & Hosting
Course outline▾

Week 4 · Enterprise Workflows

  1. Day 22Autonomous Agents: From Passive LLMs to Goal-Driven ExecutionComing soon · 2026-10-22 · 7 PM IST
  2. Day 23Tool Use & Function Calling: Connecting LLMs to APIs, Databases, and ShellsComing soon · 2026-10-23 · 7 PM IST
  3. Day 24Multi-Agent Orchestration: Supervisor, Worker, and Evaluator PatternsComing soon · 2026-10-24 · 7 PM IST
  4. Day 25Automated CI/CD: Automating the Software Lifecycle for AI ModelsComing soon · 2026-10-25 · 7 PM IST
  5. Day 26Zero-Trust Security for AI: Sandboxing Ephemeral Execution & Model EgressComing soon · 2026-10-26 · 7 PM IST
  6. Day 27Observability & Tracing for Agentic Systems (Telemetry, Logs, and Metrics)Coming soon · 2026-10-27 · 7 PM IST
  7. Day 28Human-in-the-Loop Architecture: Machine Second, Human First in PracticeComing soon · 2026-10-28 · 7 PM IST
  8. Day 29Managing Technical Debt, Drift, and Model Governance in Enterprise ITComing soon · 2026-10-29 · 7 PM IST
  9. Day 30The 10-Year Horizon: Architecting IT Strategy for the AI-Native EnterpriseComing soon · 2026-10-30 · 7 PM IST
Open the course page →

Day 17: Containerizing AI Workloads — Production Dockerfiles for Python APIs

2026-10-17 · 7 min read

Watch the video lesson, or subscribe on YouTube for a new lesson every day.

Moving a model from a notebook to a service means putting it in a container. But AI images are not like a Node.js or Go service. Deep learning frameworks bring heavy CUDA shared libraries, C++ build tools and multi-gigabyte wheel files, and a careless Dockerfile can balloon past 10 GB.

In plain terms: Imagine shipping a finished chair. A naive Dockerfile mails the chair together with the whole workshop: saws, sawdust and offcuts. A multi-stage build ships only the chair.

A naive AI image gets huge Naive: pip install everything in one imagebase OScompilersbuild cachesCUDA + torchyour appMulti-stage: ship only what runsbaseCUDA + torchappNo compilers, no caches: smaller and safer.Bar widths are illustrative. Real sizes depend on your dependencies.
A naive Dockerfile that installs everything in one image ends up carrying compilers and build caches along with the large CUDA and PyTorch libraries. A multi-stage build ships only the runtime pieces. The bar widths are illustrative.

The anatomy of a bloated image

A naive Dockerfile that runs RUN pip install torch transformers fastapi in a default base image causes three operational problems.

Three problems with a naive image Layer duplicationbuild caches stay trapped in image layers, so pushes and pulls get slowSecurity exposuregcc and make left in production widen the attack surfaceSlow scalinghuge images delay new pods when traffic spikesEach one is fixed by the same habit: build lean.
A naive AI image duplicates build caches inside its layers, leaves compilers in production which widens the attack surface, and is so large that new pods start slowly when traffic spikes.
  • Layer duplication. Build caches and downloaded wheels stay trapped in read-only image layers, which slows registry pushes and pulls.
  • Security exposure. Leaving gcc, g++ and make in the production image widens the attack surface.
  • Slow deployments. Huge images saturate the network during autoscaling, so new pods start late exactly when traffic spikes.

Three production patterns

Multi-stage builds. Split the Dockerfile in two. The builder stage has the compilers; it downloads and builds dependencies into a virtual environment at /opt/venv. The runtime stage starts from a clean, minimal base such as python:3.11-slim and copies in only that environment.

A multi-stage build, step by step Stage 1: builderHas compilers and build toolsDownloads and builds the wheelsInstalls everything into /opt/venvStage 2: runtime (python:3.11-slim)Clean, minimal base imageCOPY --from=builder /opt/venv /opt/venvRuns as a non-root user copy the venv onlyEverything in stage 1 that you do not copy is thrown away.
In stage one, the builder stage has compilers and installs every dependency into a virtual environment. In stage two, a clean slim runtime image receives only that virtual environment, and everything else from stage one is discarded.

Wheel caching. A BuildKit cache mount (--mount=type=cache,target=/root/.cache/pip) keeps pip's download cache outside the image, so repeated CI builds do not download the heavy packages again.

Non-root security. Never run the process as root. Create a dedicated user and start the ASGI server as that user.

Production checklist ✓Multi-stage buildbuilder compiles, runtime only runs✓Cache pip downloadsBuildKit cache mount keeps CI builds fast✓Never run as rootcreate a user, then start uvicorn as it✓Pin your versionssame inputs give the same imageReproducible, auditable and ready for a cluster scheduler.
A production-ready AI image uses a multi-stage build, caches pip downloads with a BuildKit cache mount, runs the server as a non-root user and pins its dependency versions, so builds are reproducible and auditable.

Here is a complete example for a FastAPI model server. It assumes a requirements.txt with pinned versions and an app/ folder with a main.py, and it is a template to adapt rather than a tuned production file. A GPU image would use a CUDA-enabled base and PyTorch build instead.

# syntax=docker/dockerfile:1

# ---- Stage 1: builder (has compilers, gets thrown away) ----
FROM python:3.11-slim AS builder
RUN python -m venv /opt/venv
ENV PATH="/opt/venv/bin:$PATH"
COPY requirements.txt .
RUN --mount=type=cache,target=/root/.cache/pip \
    pip install -r requirements.txt

# ---- Stage 2: runtime (clean and minimal) ----
FROM python:3.11-slim
COPY --from=builder /opt/venv /opt/venv
ENV PATH="/opt/venv/bin:$PATH"
RUN useradd -m -u 1000 appuser
WORKDIR /app
COPY --chown=appuser:appuser app/ ./app/
USER appuser
EXPOSE 8000
CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000"]

Build it with DOCKER_BUILDKIT=1 docker build -t model-api .. Writing lean, deterministic Dockerfiles turns chaotic research dependencies into reproducible, auditable artifacts that a cluster scheduler can start quickly.

Coming Up Next

Day 18: Docker Compose for multi-container AI stacks.

#Docker #Containerization #DevOps #AIEngineering #FastAPI