Multi-Stage Builds¶
Use multiple stages to keep build toolchains, source code, and intermediate files out of the runtime image.
Structure¶
# syntax=docker/dockerfile:1
FROM golang:1.23-trixie AS build
WORKDIR /src
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 go build -trimpath -ldflags="-s -w" -o /out/app ./cmd/app
FROM gcr.io/distroless/static-debian13:nonroot
COPY --from=build /out/app /app
USER nonroot
ENTRYPOINT ["/app"]
- Name stages with
AS <name>and copy only the artifacts you need withCOPY --from=<name>. - The runtime stage SHOULD contain no compilers, package managers, or source code.
- Build development or debug variants with
--target <stage>instead of shipping them by default. - A common base stage (
FROM base AS build) avoids repeating setup across stages. Chained stages (FROM build AS test) stay available for copying.
Choosing the Runtime Base¶
scratchis the smallest option but has no shell, CA certificates, timezone data, or/etc/passwd. Use it only for fully static binaries.- Distroless (
gcr.io/distroless/static-debian13,cc-debian13,base-debian13) adds CA certificates,/etc/passwd, and anonrootuser without a shell or package manager. - Use
-slimor Alpine when the application needs a shell, a package manager, or glibc/musl-specific libraries. - Static Go and Rust binaries SHOULD be built with
CGO_ENABLED=0(Go) or a static target (Rust) when targetingscratch.
Copying Artifacts¶
- Copy individual artifacts rather than whole directories;
COPY --from=build /src /srcdrags source and caches into the runtime image. COPY --fromsupports--chownand--link. Use--chownso files are owned by the runtime user from the start.- For Python and Node.js builds, install into a virtualenv or a dedicated prefix, then copy that directory into the runtime stage.
Cross-Platform Builds¶
Build on the native platform and cross-compile when the language supports it;
this avoids slow emulated builds. TARGETOS and TARGETARCH are automatic
build arguments, but they MUST be redeclared with ARG inside a stage before a
RUN can use them.