4.2.3.3 COPY Build Artifacts
A focused guide to COPY Build Artifacts, connecting core concepts with practical Docker and container operations.
Using COPY for build artifacts, particularly COPY --from=<stage>, brings the specific output of an earlier build stage — a compiled binary, bundled frontend assets, generated documentation — into a later, typically much smaller, final image stage in a multi-stage build.
Copying Output From a Named Build Stage
COPY --from references a previously defined build stage by name, copying specific files produced by that stage rather than anything else it might also contain.
FROM golang:1.22 AS build
WORKDIR /src
COPY . .
RUN go build -o app .
FROM debian:bookworm-slim
COPY --from=build /src/app /usr/local/bin/app
CMD ["app"]
Only the compiled app binary crosses into the final image; the entire Go toolchain and source code used to produce it remain behind in the discarded build stage.
Copying From an External Image Entirely
COPY --from can also reference an entirely separate, already-published image rather than a stage defined within the same Dockerfile, useful for borrowing a specific tool or artifact from another image without installing it directly.
COPY --from=golangci/golangci-lint:latest /usr/bin/golangci-lint /usr/local/bin/golangci-lint
This brings a linting tool's binary directly from its own published image, without needing to install it through a package manager.
Copying Multiple Artifacts From Different Stages
A Dockerfile with several build stages can selectively copy different artifacts from each into a single final stage, assembling the final image from pieces produced independently.
FROM node:20 AS frontend
WORKDIR /app
RUN npm run build
FROM golang:1.22 AS backend
WORKDIR /src
RUN go build -o server .
FROM debian:bookworm-slim
COPY --from=frontend /app/dist /var/www
COPY --from=backend /src/server /usr/local/bin/server
Why Copying Build Artifacts This Way Matters
This pattern is central to keeping final production images minimal: the often large, tool-heavy environments needed to build an application are entirely separate from what actually ships, with only the specific, necessary output ever crossing into the final image.