5.3.2 Final Runtime Stage
A focused guide to Final Runtime Stage, connecting core concepts with practical Docker and container operations.
The final runtime stage is the last stage in a multi-stage Dockerfile, representing the actual image that gets tagged, pushed, and run in production — built on a minimal base appropriate for running (not building) the application, containing only what is needed at runtime.
Defining the Final Stage
The final stage typically starts from a much smaller base than any builder stage that preceded it, since it only needs to run the already-built application, not compile or bundle it.
FROM golang:1.22 AS builder
WORKDIR /src
COPY . .
RUN CGO_ENABLED=0 go build -o /out/app .
FROM gcr.io/distroless/static-debian12
COPY --from=builder /out/app /app
ENTRYPOINT ["/app"]
The final stage here uses a distroless base containing essentially nothing beyond what's needed to run a statically compiled binary.
What the Final Stage Should and Shouldn't Contain
The final stage should contain the application itself, any runtime configuration it needs, and nothing else — no compilers, no build tools, no test code, no development dependencies.
FROM node:20-alpine
COPY --from=builder /app/dist /app/dist
COPY --from=builder /app/node_modules /app/node_modules
CMD ["node", "dist/server.js"]
This copies only the built output and production dependencies, not the original source files or development tooling used during the build.
Verifying the Final Stage Is Actually Minimal
Inspecting the final image's contents and size confirms the final stage genuinely reflects a minimal runtime environment, rather than accidentally inheriting more than intended.
docker images myapp
docker run --rm myapp:1.0 ls /
Why the Final Runtime Stage Matters
The final stage is what actually gets deployed and run, making it the stage where every size, security, and dependency decision has the most direct, lasting consequence — every other stage in a multi-stage build exists ultimately in service of producing this one well.