Compose, Registries & Image Hygiene
- Orchestrate a multi-service stack (API + vector DB + cache) with Docker Compose
- Add healthchecks and service dependencies so the stack starts in the right order
- Shrink images with multi-stage builds and slim bases, and tag them sensibly
- Push to a registry and understand image scanning and tag hygiene
| Spaced-rep warm-up: Docker + vector DB cards (D148/D115) | 10 min |
| ELI5 + tech read: Compose, healthchecks, multi-stage, registries | 20 min |
| Guided: compose the stack + measure the multi-stage shrink | 40 min |
| Practice: tagging & rollback scheme + push | 15 min |
| Project: compose the stack + ship a hygienic image | 25 min |
| Quiz + flashcards | 10 min |
Builds on: Day 47 β Caching & queues Β· Day 115 β Embeddings & vector databases Β· Day 148 β Docker fundamentals
One container is a kitchen. But your docs-QA service isn't one kitchen β it's a small restaurant: the API that talks to customers, a vector database that holds the meaning-indexed documents, maybe a cache so repeated questions are cheap. Starting each by hand, in the right order, wiring them so they can find each other, and remembering every port and password β that's a checklist you'll get wrong at 6pm on a Friday.
Docker Compose is the fleet manifest: one file that declares every service, how they connect, what each needs to be healthy, and which must start before which. docker compose up and the whole restaurant comes online, wired together, every time identically. Two more habits come with running a fleet. First, image hygiene: a bloated image is slow to ship and full of things that can break or be attacked, so you trim it with multi-stage builds β do the heavy assembly in a back room and carry only the finished dishes into the dining room. Second, the registry: the shared warehouse where finished images are stored and versioned, so the server pulls the exact image you built and tagged, not a mystery rebuild. Manifest, hygiene, warehouse β that's how you run more than one container without losing your mind.
Real AI services are never a single process. Your capstone needs its vector store and, soon, a cache β and "works on my machine" returns with a vengeance when three services have to find each other. Compose makes the whole stack reproducible in one command, which is what lets a teammate (or a customer's engineer, Day 170) run your entire system locally to evaluate it. Image hygiene is money and security: a 1.2GB image costs bandwidth and cold-start time on every deploy and carries a bigger vulnerability surface; a 200MB multi-stage image deploys faster and scans cleaner β the kind of detail a customer's security review (Day 159) checks. Registries and tag discipline are what make Day 152's CI/CD and Day 158's rollback even possible: you can only roll back to a version you tagged and stored.
Guided practice
Compose the full capstone stack locally
22 min- Add a
compose.yamlto your capstone from the tech section, adapting the vector DB image to whatever you use (Qdrant or a pgvector Postgres image) and pointing the API's env at the service names. - Make the API read
QDRANT_URL/REDIS_URLfrom env (not hardcoded localhost) so it connects over the Compose network. - Bring it up: terminal:
docker compose up --build. Watch the vector DB become healthy *before* the API starts accepting traffic. - Hit the API: terminal:
curl localhost:8000/healththen run one real docs-QA query β confirm it reaches the vector DB by service name. - Tear down but keep data: terminal:
docker compose down(volumes persist), thenupagain and confirm the index survived. - Check ordering works: temporarily remove the vectordb healthcheck and observe the API racing/failing on boot β then restore it.
Multi-stage build: measure the shrink
18 min- Record your Day-148 single-stage image size: terminal:
docker images docsqa. - Convert the Dockerfile to the multi-stage version from the tech section (builder venv β slim final).
- Rebuild and compare sizes side by side. terminal:
docker build -t docsqa:slim . && docker images docsqa. Note the reduction. - Confirm the slim image still runs the full stack (rebuild via compose or run directly) and answers a query.
- Scan both images if you have Docker Scout: terminal:
docker scout quickview docsqa:devanddocker scout quickview docsqa:slimβ compare the CVE counts and connect fewer packages to fewer vulnerabilities. (If Scout is unavailable, list installed packages in each withdocker run --rm IMAGE pip listanddpkg -land reason about surface area.)
On your own
Design your tagging and rollback scheme
15 minIn writing, design the image-tagging strategy your capstone will use through Days 152β158. Specify: (1) the immutable tag format (e.g. git SHA) and why latest alone is unsafe for deploys; (2) any human-friendly aliases you keep (e.g. a staging/prod moving tag pointing at a SHA) and the rule for moving them; (3) exactly how a rollback works with your scheme β the command sequence to revert to the previous good build; (4) where scanning fits (block a push if criticals? warn?). Then actually tag your slim image with a SHA-style tag and (if you have a registry account) push it to ghcr.io or Docker Hub; otherwise write the exact docker tag / docker push commands you would run.
Hints: the rollback story is the acid test β if you can't name the previous artifact by an immutable tag, you can't roll back to it. A moving prod tag is convenient but must always be pinned to a specific SHA in your deploy records.
Compose the stack + ship a hygienic image
Make your capstone a one-command, production-shaped stack. Deliver: a compose.yaml bringing up API + vector DB + cache with healthchecks and correct startup ordering, a multi-stage Dockerfile that meaningfully shrinks the image versus Day 148 (record before/after sizes), and a docker/HYGIENE.md documenting the base-image choice, the multi-stage split, your tag scheme (immutable SHA tags, no bare latest for deploys), and the rollback procedure. Prove: docker compose up starts the whole stack cleanly and a real docs-QA query works end to end over the Compose network; the vector index persists across compose down/up; and the image is tagged and either pushed to a registry or accompanied by the exact push commands. Note any CVEs surfaced by a scan and your remediation stance.
Common mistakes & misconceptions
- Using depends_on without a healthcheck condition. Plain depends_on only waits for the process to start, not to be ready β the API races the vector DB on boot and intermittently fails.
- Hardcoding localhost between services. Inside Compose, services reach each other by service name (vectordb:6333), not localhost β localhost is the container itself.
- Deploying the :latest tag. It is a moving target, so two deploys can run different code and rollback is impossible; tag with the immutable git SHA.
- Shipping the build toolchain in the runtime image. Compilers and pip caches bloat the image and widen the attack surface β multi-stage copies only the finished artifacts.
- Committing the vector index and cache data into the image. State belongs in volumes; baking it in makes images huge and stale and leaks data.
- Ignoring scan results because the app works. Known CVEs in base layers are exactly what a customer security review flags β smaller, patched bases are the cheap fix.
Q1. In Compose, how does the API service address the vector database?
Q2. What does a multi-stage build primarily achieve?
Q3. Why tag deploy images with the git commit SHA instead of `latest`?
Go deeper β curated resources
- GitHub Container Registry (ghcr.io) β β Push your slim image to ghcr.io and pull it on another machine β this is exactly the artifact Day 152's CI will build and Day 151's host will pull.
- compose up brings API + vector DB + cache online with correct ordering
- Real docs-QA query works over the Compose network; index persists across down/up
- Multi-stage image measurably smaller than Day 148; sizes recorded
- Immutable tag applied and pushed (or exact push commands written); rollback documented
- Quiz β₯ 2/3
β Back: This wires the Day-148 image together with the Day-115 vector database and a Day-47 cache into one reproducible stack, and applies Day 141's pin-the-version discipline to image tags.
Forward β: Day 151 deploys this exact stack to the cloud, Day 152 builds and pushes these tagged images in CI, Day 156 adds the semantic cache to the cache service, and Day 158 relies on your immutable tags to roll back an incident.
Unlocks: D150 Cloud Fundamentals Β· D151 Deploy Lab β Container to Cloud URL Β· D154 Week 22 Checkpoint: Staging Pipeline