Dockerfile Revisited

Published by Bill on (Updated: )

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?