735 words
4 min read

Building AI Solutions with Docker Compose and Kubernetes Expertise

By · Docker Captain · CNCF Ambassador · IBM Champion
2024-05-13
2026-06-16
Cover image for the post 'Building AI Solutions with Docker Compose and Kubernetes Expertise'

You’re building AI workloads. So you’re juggling Python packages, GPU drivers, REST APIs, databases, maybe a Kafka pipeline on top of all that. And if you’re still herding it with bash scripts and hope?
You’re doing it wrong.

This guide is about how Docker Compose tames the chaos of a modern AI project. Not the toy version. The version someone runs when they’ve actually shipped containers in production instead of poking at notebooks.

I’ll get into the real usage. Environment handling. Image pull policies. Secrets, resource limits, and the one command, docker compose watch, that saves your sanity during dev cycles. There’s also the part nobody enjoys: handing your Compose stack off to Kubernetes without rage-quitting.

Compose 2.x: A Dev Tool That Grew Up#

Compose is still your best friend for local work. No argument there. But it’s also a serious CI/CD asset now, and a good staging orchestrator, if you know how to drive it.

Enough preamble.

Environment Variable Precedence: Know Who Wins the Fight#

By default, Compose favors your shell environment over whatever sits in your .env file.

So this:

Terminal window
export DATABASE_URL=postgres://prod.db

…will override this in .env:

DATABASE_URL=postgres://dev.db

Good. That’s exactly the behavior you want in CI/CD, where secrets have no business touching source control.

📖 Environment Variables — Compose Docs

Controlling Image Pulls: Don’t Get Burned by Stale Containers#

There are two clean ways to pull fresh images.

  1. Force it every time:

    Terminal window
    docker compose up --pull always
  2. Lock it in the Compose file:

    services:
    app:
    image: my-image:latest
    pull_policy: always

pull_policy supports: always, if_not_present, and never.

Use it. Skip it and you’ll burn an afternoon debugging a bug that doesn’t exist, because CI quietly served a stale image from cache while you screamed at your pipeline.

SSH & Secrets: Handling Sensitive Stuff Like an Adult#

BuildKit is the default now. That buys you real control over build-time secrets and SSH access.

SSH During Builds#

Need to clone a private repo mid-build?

services:
app:
build:
context: .
ssh:
- default=/home/user/.ssh/id_rsa

The key never lands in the image. No more “oops I leaked my SSH key to Docker Hub”.

Runtime Secrets#

Compose doesn’t do Docker Swarm-style secrets. You can fake it with mounted files or env vars. Or, if you’re serious about it, wire in a vault.

📖 SSH & Secrets in Compose

Live Reloads with docker compose watch: Real Dev Speed#

You want a tight feedback loop. That’s what the watch command is for.

Real-World Example: Node.js App#

services:
app:
image: node:18
volumes:
- .:/app
working_dir: /app
command: npm start
environment:
NODE_ENV: development
ports:
- "3000:3000"
labels:
com.docker.compose.watch: "true"

Then run:

Terminal window
docker compose up
docker compose watch

Change a file locally and the container picks it up. No rebuild. No restart. No staring at the screen wondering why your fix didn’t take.

📖 Docker Compose Watch Docs

Override Files: Keep Dev and Prod from Colliding#

Still cramming every config into one compose.yaml? Stop. Split it:

  • compose.override.yaml for local tweaks
  • docker compose -f base.yaml -f prod.yaml to layer configs
  • include: blocks, if you’re on Compose v2+ and feeling fancy

It’s cleaner, it’s safer, and it’s a lot easier to debug when something breaks at 2am.

📖 Extending Compose Files

YAML Anchors: DRY or Die#

Compose files turn into spaghetti fast. Anchors fix that:

x-default-env: &default-env
NODE_ENV: production
services:
web:
image: webapp
environment: *default-env
api:
image: apiserver
environment:
<<: *default-env
DEBUG: true

Less repetition, fewer bugs, and a file you can actually read six months from now.

📖 Compose File Fragments

Resource Limits: Be a Good Container Citizen#

Even on a dev cluster, don’t let one container eat the whole node.

services:
ai-worker:
image: my-ai-image
deploy:
resources:
limits:
cpus: "1.0"
memory: "1G"
reservations:
cpus: "0.5"
memory: "512M"

Now, a caveat. deploy is ignored by docker compose in local mode. But the second you hand this off to Swarm or translate it to Kubernetes, you’ll be glad it was already there.

Compose to Kubernetes: The Good, The Bad, and The “Use Kompose”#

Want to turn a Compose stack into Kubernetes YAMLs? Kompose does it, and the output isn’t terrible.

Terminal window
kompose convert

You’ll still have homework:

  • Set up Ingress and controllers by hand
  • Configure PVCs and storage
  • Handle secrets the Kubernetes way

For MVPs and small internal tools, though, it works fine.

Just don’t ship the raw output to production. Clean it up first.

Final Take#

Docker Compose stopped being a one-trick Redis-launcher a while ago. Driven well, it’s a serious tool, and it earns its keep most in AI workflows, the kind that sprawl across a dozen services.

It lets you:

  • Develop locally at full speed
  • Keep secrets out of your images
  • Cut downtime during builds
  • Hand off to Kubernetes when the time comes

If you’re shipping AI services and you’re not using Compose properly, you’re just making the job harder than it is.

📖 Read the Full Compose Docs


Vladimir Mikhalev

Docker Captain  ·  CNCF Ambassador  ·  IBM Champion

The Verdict — production-tested analysis on YouTube.

The Verdict

Inconvenient truths about shipping in the AI era

Container security, platform engineering, and the agentic shift — tested in production, argued without the hype. The verdict reaches your inbox the moment there's one worth sending.

Related Posts

Same category
  1. 1
    AI-BOM at Admission — The Cluster Refused a Signed Model for Its Licence
    AI & MLOps · An AI-BOM read at admission. Everything crosses the air gap as one signed file, and a signed model is refused for its licence. CycloneDX, Kyverno, cosign.
  2. 2
    Prompt Injection Evals — Six Models, One Boundary, Nothing Left the Company
    AI & MLOps · Prompt injection evals on six small models. They acted on hidden instructions from never to half the time, and zero data left. Gate the boundary.
  3. 3
    AI Agent Governance — One Engineer, Over a Hundred Repositories and the Decisions No Agent Makes
    AI & MLOps · AI agent governance for one engineer and 100+ repositories. What the agents decide, what they never do, and the documented auto-merge that merges red checks.
  4. 4
    AI Reviews That Read Nothing — Thirty-Four Verdicts in a Hundred
    AI & MLOps · A third of the images my fleet pins would have had their next AI review written against nothing. How to prove what an AI review read before anyone acts on it.

Random Posts

Random
  1. 1
    Install Homebox with Docker Compose, Traefik and Let's Encrypt
    Self-Hosting · Homebox home inventory behind Traefik with Let's Encrypt certificates: the Docker networks, the compose file from my repository, one command, first login.
  2. 2
    Mutation Testing for Infrastructure Code — 153 Planted Bugs, Four Tests That Could Not Fail
    DevOps & Cloud · Mutation testing for infrastructure code, done by hand across fifteen repositories. 153 planted bugs, and four green tests that could never have failed.
  3. 3
    Install Puppet Server and Agent on Ubuntu, Certificates Included
    DevOps & Cloud · Puppet Server and a Puppet agent on Ubuntu, from hostnames and NTP to certificate signing and a first manifest, with every command in order.
  4. 4
    Install Active Directory Domain Services on Windows Server 2019 Server Core
    SysAdmin & IT Pro · Learn how to install and configure Active Directory Domain Services on Windows Server 2019 Server Core using PowerShell. Step-by-step setup for your AD DS role.
Building AI Solutions with Docker Compose and Kubernetes Expertise
https://heyvaldemar.com/building-ai-solutions-with-docker-compose-and-kubernetes-expertise/
Author
Vladimir Mikhalev
Published
2024-05-13
Updated
2026-06-16
License
CC BY-NC-SA 4.0