Skip to content

Multi-stage Docker builds

Multi-stage builds are a Docker feature designed to optimize the size of the final image by separating the build environment from the runtime environment^[400-devops-06-kubernetes-k8s-ithelp-day6-readme.md]. Instead of packaging the compiler, source code, and intermediate dependencies into the final container, this technique allows artifacts to be copied from a "builder" stage into a fresh, minimal "runtime" stage^[400-devops-06-kubernetes-k8s-ithelp-day6-readme.md].

Mechanics

In a standard Dockerfile, every layer created by RUN, COPY, or ADD instructions adds to the final image size^[400-devops-06-kubernetes-k8s-ithelp-day6-readme.md]. Multi-stage builds solve this by using multiple FROM instructions within a single Dockerfile^[400-devops-06-kubernetes-k8s-ithelp-day6-readme.md]. Each FROM instruction begins a new, independent build stage.

Artifacts can be transferred between stages using the COPY --from flag^[400-devops-06-kubernetes-k8s-ithelp-day6-readme.md]. This allows developers to copy compiled binaries or processed assets from the build stage into the final stage without carrying over the language SDKs or build tools used to create them.

Example: Go to Alpine

The following example demonstrates compiling a Go application in a full-featured environment and running it in a minimal Linux container^[400-devops-06-kubernetes-k8s-ithelp-day6-readme.md]:

# Build stage
FROM golang:1.18-rc-alpine as builder
WORKDIR /
COPY . .
RUN go mod tidy
RUN go build -o main

# Runtime stage
FROM alpine:3.15.0-rc.4
WORKDIR /
# Copy only the binary from the builder stage
COPY --from=builder /main .
EXPOSE 8080
ENTRYPOINT ["./main"]

In this scenario, the final image contains only the compiled main executable and the minimal Alpine base, significantly reducing the footprint compared to an image based on the full Go SDK^[400-devops-06-kubernetes-k8s-ithelp-day6-readme.md].

Benefits

  • Reduced Image Size: By discarding build tools and source code, the final image is much smaller, which speeds up deployment and reduces storage costs^[400-devops-06-kubernetes-k8s-ithelp-day6-readme.md].
  • Improved Security: Fewer binaries and packages in the final image mean a smaller attack surface.
  • Simplified Maintenance: The entire build and runtime process is defined in a single file, removing the need for complex scripts to clean up intermediate files.

Sources

^[400-devops-06-kubernetes-k8s-ithelp-day6-readme.md]