Docker Builds With Private Go Modules
DevOpsWhen 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"]