docker and private go modules

Medina’s Arte de navegar, Vallodolid, 1545

Recently I ran into having to build a go docker image with a private go module hosted in GitHub. Unhappy with the current answers online, I wanted to share what I settled on.

FROM golang:1.21 as build

WORKDIR /go/src/app
COPY . .

RUN mkdir -p -m 0600 ~/.ssh && ssh-keyscan github.com >> ~/.ssh/known_hosts
RUN git config --global url."git@github.com:".insteadOf https://github.com/ && git config --global url."git://".insteadOf https://
RUN --mount=type=ssh go mod vendor
RUN CGO_ENABLED=0 go build -o /go/bin/app

FROM gcr.io/distroless/static-debian11
COPY --from=build /go/bin/app /

EXPOSE 8080

CMD ["/app"]

a little magic here: --mount=type=ssh mounts a socket with read-only access to the host machine’s ssh agent. This runs only during the associated RUN step:

RUN --mount=type=ssh go mod vendor

I also love nice and tiny distroless images:

FROM gcr.io/distroless/static-debian11
COPY --from=build /go/bin/app /