Docker Builds With Private Go Modules

DevOps

When retrieving Go apps with private modules you need to authenticate against whatever git repo your module is in. When you search the internet it advises you to utilize a .netrc file to configure the basic auth credentials.

When the go compilation is run as a gitlab step it works fine. However, if you try a multistage docker build with the compilation done as part of the Dockerfile it fails to pull the private modules. So why does the .netrc work in the gitlab job which is just a docker image and not in the multi stage build?

Hours of googling didn’t yield anything just people helpfully saying to use the .netrc would fix the problem. Even execing into a docker container and running the build worked.

docker exec -it <container> /bin/ash

After a lot poking and prodding I finally realized that during a docker build the default shell is sh and when I exec’d in or ran it as a gitlab job it was using bash|ash.

So then I had to figure out how to change the shell during a build step. Turns out there is a SHELL directive to configure and change the shell during the build.

It looks like this for alpine images:

SHELL [ "/bin/ash", "-c" ]

And this for bash available images:

SHELL [ "/bin/bash", "-c" ]

The .netrc looks something like this:

machine gitlab.com
  login <username>
  password <access.token>

Then putting it all together looks like this:

ARG GITLAB_TOKEN
FROM golang:1.21-alpine3.19 AS builder


COPY ${PWD} /app
WORKDIR /app

RUN echo -e 'machine gitlab.com\n\tlogin <username>\n\tpassword ${GITLAB_TOKEN}' > .netrc

SHELL [ "/bin/ash", "-c" ]

RUN CGO_ENABLED=0 go build -ldflags '-s -w -extldflags "-static"' -o /app/appbin *.go

FROM alpine:3.19

RUN apk --update add ca-certificates && \
    rm -rf /var/cache/apk/* && \
    adduser -D appuser


COPY --from=builder /app/appbin /home/appuser/app/appbin

USER appuser

WORKDIR /home/appuser/app

CMD ["appbin"]
DockerGoMulti-Stage DockerDevOpsContainersShellContinuous IntegrationBashGitlab CI/CD