Dockerfile Revisited

Published by Bill on

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?