Build cache and image size

Docker · lesson 8 of 31 · 4 min read

Order layers so rebuilds take seconds, and keep the final image small on purpose.

Open this lesson in the learning hub

Key points

  • A layer is reused only if its instruction and inputs are unchanged. One miss invalidates every layer after it.
  • So order from least-changing to most-changing: base image, then dependencies, then your source code.
  • BuildKit is the default builder since Docker 23. RUN --mount=type=cache keeps the Maven repo warm without baking it into a layer.
  • Spring Boot 3.3+ can split a fat jar: java -Djarmode=tools -jar app.jar extract --layers gives dependencies their own layer.
  • Clean up inside the same RUN that made the mess. A later rm hides bytes but still ships them.
  • docker image history tells you which instruction cost the megabytes. Read it before you start guessing.

Example

FROM maven:3.9-eclipse-temurin-21 AS build
WORKDIR /src

# cache mount: ~/.m2 is reused between builds and never enters a layer
COPY pom.xml .
RUN --mount=type=cache,target=/root/.m2 mvn -B -q dependency:go-offline

COPY src ./src
RUN --mount=type=cache,target=/root/.m2 mvn -B -q package -DskipTests

# where did the size go, and what did the builder actually do?
#   docker image history myapp:1.0 --no-trunc
#   docker build --progress=plain -t myapp:1.0 .

Cheap, stable layers first. Your source code goes last.

This is a reading copy. The full lesson — with the visual explainer, the interactive lab and a Run button for the code — lives in the Docker course, and every lesson in it is listed on the Docker contents page.