Cover image for Go private packages

Go private packages

yuriizinets profile image Yurii Zinets ・2 min read

git submodules

What's the matter?

Imagine a situation when you're following best practices, splitting your code on different parts, and ... facing an issue to collect them.
Unfortunately, go does not support private packages well.

So, how?

I'll describe the situation I faced. Private go mod packages, located in the GitLab subgroup (let's say gitlab.com/org/department/repo1.git just for example)

First, go not actually supports GitLab subgroups. To bypass that issue, we need to set GOPRIVATE env variable and add .git in the end:

$ GOPRIVATE="gitlab.com/org/department" go get gitlab.com/org/department/repo1.git 

Second barrier is access to that repo. SSH key must be added to the platform, I didn't found a way to fetch with https.


  • Native experience (go get, which handles go.mod changes itself)


  • SSH key must be set
  • go.mod package name must fully correspond that naming (with .git in the end)

Problem is solved ... or not?

The first problem was faced in just after half an hour. It's a CI/CD, or just building step.
As we understood from previous "summary", SSH key must be added. We are using Docker to build our project, and passing SSH key to the Dockerfile build actually is a security problem.

Alternative way

I found a solution in git submodules and replace feature for the go.mod.
Just add needed repo as a project submodule with git submodule add and add naming replacement in the go.mod.
For example:

Adding submodule

$ git submodule add ../repo1

Pulling newly added repo

$ git submodule update --init

Adding go.mod replacement

replace gitlab.com/org/department/repo1.git => ./repo1

And that's all! Handling package as a submodule is much easier than go package.

P.S. Don't forget to add submodules pulling in your CI! In case of GitLab it's GIT_SUBMODULE_STRATEGY: recursive variable.

Thank you for reading!

Don't forget to check my packages :)


Editor guide