0
0
Dockerdevops~5 mins

Multi-stage builds concept in Docker - Commands & Configuration

Choose your learning style9 modes available
Introduction
Building Docker images can create large files if all build tools stay inside the final image. Multi-stage builds let you use multiple steps to build your app, keeping only the final needed parts. This makes images smaller and faster to use.
When you want to compile code inside a container but keep the final image small.
When your app needs build tools that are not needed at runtime.
When you want to separate build environment from runtime environment in one Dockerfile.
When you want to reduce image size to save bandwidth and storage.
When you want to speed up deployment by using smaller images.
Config File - Dockerfile
Dockerfile
FROM golang:1.20 AS builder
WORKDIR /app
COPY . .
RUN go build -o my-app

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

This Dockerfile has two stages:

  • builder: Uses the golang image to compile the Go app.
  • final: Uses a small Alpine Linux image and copies only the compiled app from the builder stage.

This keeps the final image small by excluding build tools.

Commands
Builds the Docker image using the Dockerfile in the current folder. It runs all stages and creates the final image named 'my-go-app'.
Terminal
docker build -t my-go-app .
Expected OutputExpected
[+] Building 10.3s (10/10) FINISHED => [internal] load build definition from Dockerfile => => transferring dockerfile: 137B => [internal] load .dockerignore => => transferring context: 2B => [internal] load metadata for docker.io/library/golang:1.20 => [builder 1/4] FROM docker.io/library/golang:1.20@sha256:... => [builder 2/4] WORKDIR /app => [builder 3/4] COPY . . => [builder 4/4] RUN go build -o my-app => [final 1/3] FROM docker.io/library/alpine:3.18@sha256:... => [final 2/3] WORKDIR /app => [final 3/3] COPY --from=builder /app/my-app . => exporting to image => => exporting layers => => writing image sha256:... => => naming to docker.io/library/my-go-app
Shows the image named 'my-go-app' to verify it was created and to check its size.
Terminal
docker images my-go-app
Expected OutputExpected
REPOSITORY TAG IMAGE ID CREATED SIZE my-go-app latest abcdef123456 10 seconds ago 12MB
Runs the container from the 'my-go-app' image to verify the app works as expected.
Terminal
docker run --rm my-go-app
Expected OutputExpected
Hello from my Go app!
--rm - Automatically removes the container after it stops to keep the system clean
Key Concept

If you remember nothing else from this pattern, remember: multi-stage builds let you separate building your app from running it, so your final Docker image stays small and efficient.

Common Mistakes
Copying source code directly into the final stage instead of copying only the built artifact.
This includes unnecessary build files and tools in the final image, making it large.
Use COPY --from=builder to copy only the compiled app or necessary files from the build stage.
Using a single stage Dockerfile with all build tools installed in the final image.
The final image becomes large and slower to deploy.
Use multi-stage builds to keep build tools only in the builder stage.
Summary
Multi-stage builds use multiple FROM statements to create separate build and final stages.
The final stage copies only the needed files from the build stage to keep the image small.
Build the image with docker build and verify it with docker images and docker run commands.