Chapter Five

Building Well

The naive Driftwood image from Chapter 4 is 1.1 GB, runs as root, and bakes its build toolchain and pip cache into the shipped layers. This chapter rebuilds it into a 180 MB slim image with the database password supplied as a build secret — through BuildKit, multi-stage builds, a lean context, cache and secret mounts, deliberate shrinking, and a reproducible, digest-pinned build.

6 topics

Chapter 4 produced a Dockerfile that works and an image you would never want to ship: 1.1 GB on disk, the full compiler toolchain and pip cache fused into the layers, and a database password sitting readable in docker history. This chapter fixes all of it without changing what Driftwood does — same app, same gunicorn process on :8000, a fraction of the size and none of the leaks.

The spine is the multi-stage build, which alone takes Driftwood from 1.1 GB to roughly 180 MB by leaving the compilers in a discarded builder stage. Around it sit the pieces that make a build fast, small, and trustworthy: BuildKit as the engine that powers the modern --mount instructions, a .dockerignore that keeps the context lean and secrets out of it, cache and secret mounts that fix the worst build-time habits, a deliberate teardown of where the bytes go, and the digest pinning that makes "what shipped in 1.4.0" answerable to the exact byte.

Topics in This Chapter

Topic 27
BuildKit — The Modern Builder
The default build engine that parses the whole Dockerfile into a graph, builds independent steps in parallel, and caches by content. The buildx front door, the DOCKER_BUILDKIT=1 switch, and the # syntax line that unlocks --mount.
BuilderBuildKit
Topic 28
Multi-Stage Builds
The chapter spine. A throwaway builder stage compiles the wheels; a slim runtime stage takes only the artifacts across with COPY --from. The single change that drops Driftwood from 1.1 GB to 180 MB.
BuildLayers
Topic 29
.dockerignore and a Small Context
The allow/deny list that keeps .git, virtualenvs, and stray secrets out of the build context — and out of the image when a careless COPY . . would otherwise bake them in. The cheapest fix in the chapter.
ContextSecurity
Topic 30
Cache Mounts and Build Secrets
Two BuildKit-only RUN --mount modes. A cache mount persists pip and apt downloads across builds without becoming a layer; a secret mount hands one step the database password and leaves nothing in history — the real fix for the ARG footgun.
CachingSecrets
Topic 31
Shrinking Images
The four levers that take an image from 1.1 GB to 180 MB: the right base, install-and-cleanup in one RUN, multi-stage to drop the toolchain, and fewer layers. Measured with docker history and dive, not guessed.
SizeOptimization
Topic 32
Reproducible Builds
Pin everything that can move: the base by digest, dependencies by lockfile, the platform explicitly. The difference between a digest you can trust in an incident review and a :latest base that shifted under you.
ReproducibilityPinning