Accessing private Go modules in a Docker container (with a PAT)

Featured image for sharing metadata for article

If you're building Docker containers which reference a private Go module, you'll likely need to work out a way to pass in credentials, so you don't have to build on your host machine.

I first encountered this last March and as I've hit it again today, I thought I'm make sure I write it up as a form of blogumentation.

This could be done by using a rewritten URL to call out to the source code provider, embedding the Personal Access Token (PAT) in the URL.

However this would be noted as a security problem:

 1 warning found:
 - SecretsUsedInArgOrEnv: Do not use ARG or ENV instructions for sensitive data (ARG "GITLAB_TOKEN") (line 5)
Sensitive data should not be used in the ARG or ENV commands
More info: https://docs.docker.com/go/dockerfile/rule/secrets-used-in-arg-or-env/

Additionally, if you were using the Git config, it would persists the secret in the layers of the image so therefore should not be used!!

(See also Why Dockerfile Build Args Shouldn't Be Used For Secrets for more details)

Instead we should instead be using secret mounts.

GitHub

Using SSH

To use SSH from the host, we can use the following Dockerfile snippet:

FROM golang:1.23

# prepare for SSH
RUN git config --global url."ssh://git@github.com".insteadOf "https://github.com"
RUN mkdir -p -m 0600 ~/.ssh && ssh-keyscan github.com >> ~/.ssh/known_hosts
# ensure that any private modules are declared here
ENV GOPRIVATE=github.com/some-org/repo

WORKDIR /app

COPY go.mod .
COPY go.sum .

RUN --mount=type=ssh go mod download

# then copy everything else
COPY . .

# and do whatever else is needed in the build
# ...

This can then be built by i.e.

# pre-requisites, via https://docs.docker.com/reference/cli/docker/buildx/build/#ssh
$ eval $(ssh-agent)

$ ssh-add ~/.ssh/id_ed25519
# or
$ ssh-add ~/.ssh/id_rsa

# then build it
$ docker buildx build --ssh default .
# or
$ docker buildx build --ssh default=$SSH_AUTH_SOCK .

Using a PAT

For the following Dockerfile snippet:

FROM golang:1.23

# prepare for PAT
# ensure that any private modules are declared here
ENV GOPRIVATE=github.com/some-org/private-go-module

WORKDIR /app

COPY go.mod .
COPY go.sum .

RUN --mount=type=secret,id=GITHUB_NETRC,dst=/root/.netrc,required=true \
	go mod download

# then copy everything else
COPY . .

# and do whatever else is needed in the build
# ...

This can then be built by i.e.

# This requires that you have pre-created a `.netrc` (via: https://www.dudley.codes/posts/2020.12.28-dockerfile-build-args-exposed/)
# ⚠️ ⚠️ ⚠️ ⚠️
# NOTE that you need to make sure that `.netrc` is in your `.gitignore`!!!
# ⚠️ ⚠️ ⚠️ ⚠️

docker build  --secret id=GITHUB_NETRC,src=./.netrc .

GitLab

Using SSH

To use SSH from the host, we can use the following Dockerfile snippet:

FROM golang:1.23

# prepare for SSH
RUN git config --global url."ssh://git@gitlab.com".insteadOf "https://gitlab.com"
RUN mkdir -p -m 0600 ~/.ssh && ssh-keyscan gitlab.com >> ~/.ssh/known_hosts
# ensure that any private modules are declared here
ENV GOPRIVATE=gitlab.com/some-org/repo

WORKDIR /app

COPY go.mod .
COPY go.sum .

RUN --mount=type=ssh go mod download

# then copy everything else
COPY . .

# and do whatever else is needed in the build
# ...

This can then be built by i.e.

# pre-requisites, via https://docs.docker.com/reference/cli/docker/buildx/build/#ssh
$ eval $(ssh-agent)

$ ssh-add ~/.ssh/id_ed25519
# or
$ ssh-add ~/.ssh/id_rsa

# then build it
$ docker buildx build --ssh default .
# or
$ docker buildx build --ssh default=$SSH_AUTH_SOCK .

Using a PAT

For the following Dockerfile snippet:

FROM golang:1.23

# prepare for PAT
# ensure that any private modules are declared here
ENV GOPRIVATE=gitlab.com/some-org/private-module

WORKDIR /app

COPY go.mod .
COPY go.sum .

RUN --mount=type=secret,id=GITLAB_NETRC,dst=/root/.netrc,required=true \
	go mod download

# then copy everything else
COPY . .

# and do whatever else is needed in the build
# ...

This can then be built by i.e.

# This requires that you have pre-created a `.netrc` (via: https://www.dudley.codes/posts/2020.12.28-dockerfile-build-args-exposed/)
# ⚠️ ⚠️ ⚠️ ⚠️
# NOTE that you need to make sure that `.netrc` is in your `.gitignore`!!!
# ⚠️ ⚠️ ⚠️ ⚠️

docker build  --secret id=GITLAB_NETRC,src=./.netrc .

Written by Jamie Tanna's profile image Jamie Tanna on , and last updated on .

Content for this article is shared under the terms of the Creative Commons Attribution Non Commercial Share Alike 4.0 International, and code is shared under the Apache License 2.0.

#blogumentation #go #docker.

This post was filed under articles.

Interactions with this post

Interactions with this post

Below you can find the interactions that this page has had using WebMention.

Have you written a response to this post? Let me know the URL:

Do you not have a website set up with WebMention capabilities? You can use Comment Parade.