tezvyn:

Docker Build Cache: Don't Rebuild What Hasn't Changed

AI-drafted, machine-checkedSource: docs.docker.comintermediate

Docker's build cache is like a saved game for your image layers. It skips rebuilding if instructions and files haven't changed. A common footgun is an early `COPY . .` command, which can invalidate the cache for all subsequent steps on every code change.

WHY IT EXISTS Building Docker images can be slow, especially for large projects with many dependencies. Re-running every step—compiling code, downloading packages—on every build is inefficient if nothing has changed. The build cache exists to avoid this redundant work and speed up development and CI/CD pipelines.

THE MENTAL MODEL Think of a Dockerfile as a recipe and each instruction as a step. The build cache is like a chef who saves the result of each step as a pre-made component (an "image layer"). If you ask the chef to cook the same recipe again, and a step's instructions and ingredients (files) haven't changed, they'll just grab the pre-made component from the pantry instead of re-doing the work.

HOW IT WORKS When you run docker build, Docker processes your Dockerfile instruction by instruction. For each instruction, it checks if it already has a cached layer from a previous build. For instructions like RUN, COPY, or ADD, Docker calculates a hash of the command itself and, for COPY/ADD, the content of the files being added. If this hash matches a previously built layer, Docker uses the cached layer (you'll see CACHED in the build log) and moves on. If it doesn't match, Docker executes the instruction, creates a new layer, and all subsequent instructions will also be executed from scratch, as their parent layer has now changed. This is why the order of instructions is critical for cache efficiency.

WHEN TO USE IT The build cache is on by default and is almost always desirable. You optimize for it by structuring your Dockerfile carefully. Place instructions that change infrequently (like installing system dependencies with RUN apt-get install) at the top, and instructions that change frequently (like COPY-ing your application source code) as late as possible.

WHEN NOT TO USE IT You might want to bypass the cache if you suspect it's using a stale version of something that Docker can't detect, like a file downloaded from a URL that has changed without the URL itself changing. You can disable it for a specific build using the --no-cache flag with docker build. This forces every single step to re-run.

ONE CANONICAL EXAMPLE Consider a Node.js Dockerfile. A poorly structured file might be: COPY . . then RUN npm install. Here, any change to any file in your project invalidates the cache for COPY, forcing a slow npm install every time. A better structure is: COPY package.json package-lock.json ./ then RUN npm install then COPY . .. Now, npm install only re-runs if your dependencies change. The final COPY only invalidates the cache for itself, which is a fast operation.

Read the original → docs.docker.com

Get five bites like this every day.

Tezvyn delivers a daily feed of 60-second tech bites with quizzes to lock in what you learn.