Complete Guide to Pulling Private Go Modules: Credential Setup & Vanity URLs for Individuals and Teams
The article explains why private Go modules often cause pain points such as scattered credential storage, import path lock‑in, and scaling issues, then details the underlying mechanisms of GOPRIVATE, GOPROXY, GOSUMDB and GOVCS, and walks through personal and organizational solutions—including .netrc, git config rewriting, static HTML, govanityurls, and hosted services—while comparing trade‑offs and offering a decision matrix.
Unified Credential Configuration
Before tackling specific scenarios, the article clarifies the environment variables and credential mechanisms that underpin all solutions.
Two Main Credential Approaches
Method 1: ~/.netrc
machine github.com
login your-username
password ghp_your_personal_access_tokenUse a fine‑grained personal access token from GitHub's Developer Settings.
Method 2: git config --global url.<...>.insteadOf
git config --global url."https://oauth2:${GITHUB_TOKEN}@github.com/".insteadOf "https://github.com/"Prefer this method because it can target a specific domain or protocol. For SSH, rewrite HTTPS to SSH similarly. Store tokens in CI secret variables, not in plain scripts.
Four Environment Variables and Their Boundaries
GOPRIVATE: marks module path prefixes as private, causing the toolchain to skip public proxy and checksum verification. GOPROXY: controls how modules are fetched and cached; defaults to https://proxy.golang.org,direct. Internal proxies (e.g., Athens) can be configured. GOSUMDB: enables or disables checksum verification against sum.golang.org. Private modules usually need this disabled together with GOPRIVATE. GOVCS (Go 1.16+): restricts which VCS tools may be used for which paths; private domains often require explicit configuration.
Understanding these variables lets you diagnose most errors.
Private Module Pulling for Individual Developers
Direct Use of GitHub/GitLab Private Repos
export GOPRIVATE=github.com/tonybai/*
git config --global url."https://oauth2:${GITHUB_TOKEN}@github.com/".insteadOf "https://github.com/"Then go get github.com/tonybai/privatemodule works without any extra mapping.
Using a Personal Vanity Import Path While Hosting on GitHub/GitLab
Request https://example.me/go/privatemodule?go-get=1 to return a go-import meta tag pointing to the real repository:
<meta name="go-import" content="example.me/go/privatemodule git https://github.com/tonybai/privatemodule">Implementation options (ordered by operational cost):
Option 1: Hand‑write a static HTML page for each module (zero cost but manual).
Option 2: Deploy govanityurls (golang.org/x tool) on a VPS behind Nginx.
Option 3: Use a hosted service like gvu (e.g., https://gomodvanityurls.com) with a single command:
gvu add example.me/go/privatemodule https://github.com/tonybai/privatemodule.gitSelf‑Hosted Git Server with Personal Vanity Path
If you run Gitea, GitLab CE, or similar on a VPS, the vanity layer can point to a different domain than the actual Git server:
<meta name="go-import" content="example.me/go/privatemodule git https://git.example.me/tonybai/privatemodule">Use the same gvu or govanityurls approaches, substituting the internal repository URL.
Private Module Pulling for Organizations / Teams
Key additional concerns: many repositories, many developers, higher availability requirements.
Use machine (bot) accounts for tokens rather than personal accounts.
Scope tokens to a repository or project, not the whole organization.
Store tokens centrally in CI secret management.
Set GOPRIVATE to the organization prefix, e.g.:
export GOPRIVATE=github.com/mycorp/*Organization‑Level Vanity Import Paths
Replace github.com/mycorp/xxx with go.mycompany.com/xxx to decouple import paths from the hosting platform and ease future migrations.
Two implementation routes:
Self‑built: Deploy govanityurls + Nginx; fully controllable but requires manual mapping updates and high‑availability engineering.
Hosted: Use gvu for one‑command mappings and built‑in high availability.
Example hosted command:
gvu add go.mycompany.com/privatemodule https://github.com/mycorp/privatemodule.gitSelf‑Hosted Git Server with Vanity Path
When the Git server lives in an internal data center, the same principles apply; the go-import meta tag points to the internal repository URL.
Decision Matrix
If you only need go get to fetch private code and don’t care about import path aesthetics, use the platform’s private repo with proper credential config.
If you want custom import paths and can operate a service, choose static HTML or self‑hosted govanityurls.
If you want custom import paths without operating a service, use a hosted solution like gvu.
For large teams with high‑availability needs, prefer hosted services or add HA to a self‑built solution.
In all cases, start by correctly configuring the four environment variables; most errors can be traced back to them.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
TonyBai
Tony Bai's tech world (tonybai.com). Not satisfied with just "knowing how", we strive for mastery. Focused on Go language internals, high-quality engineering practices, and cloud‑native architecture, exploring cutting‑edge intersections of Go and AI. Gophers who pursue technology are welcome—follow me and evolve with Go.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
