Building Small Images

Smaller images pull faster, use less disk and expose fewer vulnerabilities; achieve them with minimal bases and multi-stage builds.

Smaller images are better in almost every way: faster to build, push and pull, cheaper to store, and with a smaller attack surface.

How to shrink images

  • Choose a minimal base like alpine, slim or distroless.
  • Use multi-stage builds to leave build tools behind.
  • Combine RUN commands and clean up caches in the same layer.
  • Use a .dockerignore file to keep junk out.
  • Install only production dependencies.

Measuring size

Compare image sizes with docker images and inspect what each layer adds with docker history.

Example

Example · bash
# Compare image sizes
docker images myapp

# See how much each layer contributes to the size
docker history myapp:1.0

When to use it

  • A team switches from node:20 to node:20-alpine as the base image, reducing the image from 900 MB to 130 MB and speeding up CI pulls.
  • A Go service uses a scratch base image so the final image is just the 12 MB static binary with no OS overhead.
  • A developer combines all apt-get commands into a single RUN instruction to prevent intermediate package lists from inflating image layers.

More examples

Switch to Alpine base

Simply changing the base image tag from the default Debian-based image to Alpine cuts image size by 85%.

Example · dockerfile
# Before: 900 MB
FROM node:20

# After: ~130 MB
FROM node:20-alpine

Clean up apt cache in same layer

Chaining the cache cleanup in the same RUN instruction prevents the package list from being stored in any layer.

Example · dockerfile
RUN apt-get update \
 && apt-get install -y --no-install-recommends curl \
 && rm -rf /var/lib/apt/lists/*

Multi-stage to exclude build tools

Builds with the full Maven image but ships only the JAR in a minimal JRE Alpine image, excluding Maven and sources.

Example · dockerfile
FROM maven:3.9-eclipse-temurin-21 AS build
WORKDIR /app
COPY pom.xml .
RUN mvn dependency:go-offline
COPY src ./src
RUN mvn package -DskipTests

FROM eclipse-temurin:21-jre-alpine
COPY --from=build /app/target/app.jar /app.jar
ENTRYPOINT ["java", "-jar", "/app.jar"]

Discussion

  • Be the first to comment on this lesson.