For years I’ve been building container images by using the COPY
command to bring files from my Docker context into the build container.
FROM golang:1.22 AS build
WORKDIR /src/build
COPY . .
RUN go mod verify
RUN CGO_ENABLED=0 GOOS=linux GOARCH=arm64 go build -o /app .
FROM scratch
COPY --from=build /app .
CMD ["./app"]
Today I came across the following section in the Docker documentation.
“You’ll mostly want to use COPY for copying files from one stage to another in a multi-stage build. If you need to add files from the build context to the container temporarily to execute a RUN instruction, you can often substitute the COPY instruction with a bind mount instead.”
It turns out I should be using --mount=type=bind
instead. This is what I should be doing.
FROM golang:1.22 AS build
WORKDIR /src/build
RUN --mount=type=bind,source=./,target=/src/build \
go mod verify
RUN --mount=type=bind,source=./,target=/src/build \
CGO_ENABLED=0 GOOS=linux GOARCH=arm64 go build -o /app .
FROM scratch
COPY --from=build /app .
CMD ["./app"]
It turns out I’ve been doing it wrong all along. As to why, the documentation indicates that using bind mounts is more efficient. With my small container images I haven’t noticed any significant difference in build times.
Note: I’ve used a minimal Dockerfile for illustrative purposes. I typically include additional steps when building my container images.
What other tricks am I missing?