0
0
Dockerdevops~5 mins

Why multi-stage builds reduce image size in Docker - Why It Works

Choose your learning style9 modes available
Introduction
Docker images can become very large when they include all the tools and files needed to build an app. Multi-stage builds help by separating the build process from the final app image, keeping only what is needed to run the app and removing extra build tools.
When you want to keep your Docker images small to save disk space and speed up downloads.
When your app needs tools to build but those tools are not needed to run the app.
When you want to improve security by not including build tools in the final image.
When you want to speed up deployment by reducing image size.
When you want to keep your Dockerfile clean and organized by separating build and runtime steps.
Config File - Dockerfile
Dockerfile
FROM golang:1.20 AS builder
WORKDIR /app
COPY . .
RUN go build -o myapp

FROM alpine:3.18
WORKDIR /app
COPY --from=builder /app/myapp .
CMD ["./myapp"]

This Dockerfile has two stages:

  • builder: Uses the golang image to compile the app. It includes all build tools.
  • final: Uses a small alpine image and copies only the compiled app from the builder stage.

This way, the final image is small and contains only what is needed to run the app.

Commands
Builds the Docker image using the multi-stage Dockerfile. This compiles the app in the first stage and creates a small final image.
Terminal
docker build -t myapp:multi-stage .
Expected OutputExpected
[+] Building 10.5s (10/10) FINISHED => [builder 1/5] FROM docker.io/library/golang:1.20@sha256:... 0.0s => CACHED [builder 2/5] WORKDIR /app 0.0s => CACHED [builder 3/5] COPY . . 0.0s => [builder 4/5] RUN go build -o myapp 9.8s => [final 1/3] FROM docker.io/library/alpine:3.18@sha256:... 0.0s => CACHED [final 2/3] WORKDIR /app 0.0s => [final 3/3] COPY --from=builder /app/myapp . 0.1s => exporting to image 0.5s => => exporting layers 0.5s => => writing image sha256:... 0.0s => => naming to docker.io/library/myapp:multi-stage
Shows the size of the built image to verify it is smaller than a single-stage build.
Terminal
docker images myapp:multi-stage
Expected OutputExpected
REPOSITORY TAG IMAGE ID CREATED SIZE myapp multi-stage abcdef123456 10 seconds ago 12MB
Runs the final small image to confirm the app works correctly without the build tools.
Terminal
docker run --rm myapp:multi-stage
Expected OutputExpected
Hello from myapp!
--rm - Automatically removes the container after it stops to keep the system clean
Key Concept

Multi-stage builds reduce image size by separating the build environment from the final runtime environment, copying only the necessary files to the final image.

Common Mistakes
Copying all source files directly into the final image instead of only the built app.
This keeps unnecessary build files and tools in the final image, making it large.
Use multi-stage builds to copy only the compiled app or runtime files from the build stage.
Not naming build stages and trying to copy from unnamed stages.
Docker cannot find the source files to copy, causing build errors.
Name the build stage with AS and use that name in COPY --from=stage.
Summary
Multi-stage builds use separate stages to build and run the app, keeping the final image small.
The build stage includes all tools needed to compile the app but is not included in the final image.
Only the compiled app or runtime files are copied to a minimal base image for the final container.