/pub/docker-multi-stage-build.md


How to Shrink Your Container Using Multi-Stage Builds

· #golang #development

Every now and then I run into some huge Docker image where 99% of the size is junk left behind while the image was being built. This is especially bad when we’re dealing with Go executables, which are self-contained and usually don’t need any external resources, not even libc.

multi-stage builds

The solution is to use multi-stage builds. This way you can have two stages in your Dockerfile: a build stage that downloads whatever is needed, compiles the code, and so on, and another that just copies the executables and resources to their expected locations. This second stage doesn’t even need to be based on a distribution; it can be a scratch image, which shrinks the final size even further.

Dockerfile example

This is a small example of a Dockerfile that uses multi-stage builds to first create an executable and then build an image that contains only the executable itself and nothing else.

FROM golang:latest as build
WORKDIR /build
ADD . .
RUN CGO_ENABLED=0 GOOS=linux \
    go build -ldflags '-extldflags "-static"' -o app

FROM scratch
COPY --from=build /build/app /app
ENTRYPOINT ["/app"]

Upsides

Downsides

Good practice

Using a multi-stage build is without a doubt a good practice regardless of the language. It’s simple to implement, and the downsides are easily worked around.

Cesar Gimenes


crg.eti.br · © 2026 Cesar Gimenes · CC BY 4.0 · github · pt