Skip to content

Commit cb32d61

Browse files
authored
docs: add Private Modules howto page (#60)
* docs: add Private Modules howto page + Getting Started mention - New howto/private-modules.md: SSH, PAT, .netrc, GOAUTH, Docker, GitHub Actions, GitLab CI (including nested subgroups), troubleshooting - quickstart.md: add Private Modules section linking to howto - navigation tests: add /howto/private-modules/ * fix: GitLab scope read_repository, remove Go version refs, fix GONOSUMDB * fix: troubleshooting scope to read_repository, clarify multi-stage build safety
1 parent 3522b11 commit cb32d61

3 files changed

Lines changed: 129 additions & 0 deletions

File tree

howto/private-modules.md

Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
---
2+
layout: default
3+
title: "Private Modules"
4+
parent: "How To"
5+
description: "Configure Go private modules for GitHub and GitLab private repositories in ColdBrew services"
6+
---
7+
## Table of contents
8+
{: .no_toc .text-delta }
9+
10+
1. TOC
11+
{:toc}
12+
13+
## Overview
14+
15+
When your service depends on private Go modules (e.g., shared libraries in a private GitHub org or GitLab group), Go needs two things:
16+
17+
1. **GOPRIVATE** — tells `go` to skip the public module proxy and fetch directly from the source
18+
2. **Authentication** — credentials to access private repositories
19+
20+
ColdBrew's cookiecutter template pre-configures GOPRIVATE from the `goprivate` variable you set during project creation (defaults to `source_path/*`). You just need to set up authentication.
21+
22+
## Local Development
23+
24+
### Option 1: SSH key (recommended)
25+
26+
If you already have SSH access to your repos:
27+
28+
```bash
29+
git config --global url."git@github.com:".insteadOf "https://github.com/"
30+
# Or for GitLab:
31+
git config --global url."git@gitlab.com:".insteadOf "https://gitlab.com/"
32+
```
33+
34+
### Option 2: Personal access token via .netrc
35+
36+
```bash
37+
# GitHub
38+
echo "machine github.com login x-access-token password YOUR_PAT" >> ~/.netrc
39+
40+
# GitLab (needs read_repository scope)
41+
echo "machine gitlab.com login your-username password YOUR_PAT" >> ~/.netrc
42+
```
43+
44+
### Option 3: GOAUTH
45+
46+
```bash
47+
export GOAUTH=netrc
48+
```
49+
50+
This tells Go to use `.netrc` for authentication during module resolution.
51+
52+
## Docker Builds
53+
54+
The generated `Dockerfile` includes GOPRIVATE as a build arg. For authentication, uncomment one of the options in the Dockerfile:
55+
56+
### Personal access token
57+
58+
```bash
59+
docker build --build-arg GITHUB_TOKEN=your_pat .
60+
```
61+
62+
The Dockerfile has a commented-out section that uses this arg to create a `.netrc` file in the build stage. Since ColdBrew uses a multi-stage build, credentials in the build stage are **not** included in the final image.
63+
64+
For even stronger isolation, use a BuildKit secret mount instead of a build arg:
65+
66+
```bash
67+
docker build --secret id=netrc,src=$HOME/.netrc .
68+
```
69+
70+
### SSH agent forwarding
71+
72+
For SSH-based auth during Docker builds, use BuildKit:
73+
74+
```bash
75+
DOCKER_BUILDKIT=1 docker build --ssh default .
76+
```
77+
78+
Add to your Dockerfile build stage:
79+
80+
```dockerfile
81+
RUN --mount=type=ssh git config --global url."git@github.com:".insteadOf "https://github.com/"
82+
```
83+
84+
## GitHub Actions
85+
86+
The generated workflow includes GOPRIVATE in the `env` section. For authentication, uncomment the private modules step and add a `GO_PRIVATE_TOKEN` secret to your repo:
87+
88+
1. Create a [GitHub PAT](https://github.com/settings/tokens) with `repo` scope
89+
2. Add it as a repository secret named `GO_PRIVATE_TOKEN`
90+
3. Uncomment the "Configure private modules" step in `.github/workflows/go.yml`
91+
92+
## GitLab CI
93+
94+
The generated `.gitlab-ci.yml` includes GOPRIVATE in the variables. For authentication, uncomment the `.netrc` line in `before_script`:
95+
96+
```yaml
97+
before_script:
98+
- mkdir -p .go/pkg/mod
99+
- echo "machine gitlab.com login gitlab-ci-token password ${CI_JOB_TOKEN}" > ~/.netrc
100+
```
101+
102+
`CI_JOB_TOKEN` is automatically available in GitLab CI — no manual token setup needed.
103+
104+
### GitLab nested subgroups
105+
106+
GitLab projects nested more than one level deep (e.g., `gitlab.com/org/group/subgroup/repo`) require special handling because Go's module discovery makes unauthenticated HTTP requests to determine the repository path.
107+
108+
Use GOAUTH with `.netrc`:
109+
110+
```yaml
111+
variables:
112+
GOAUTH: "netrc"
113+
```
114+
115+
Also set `GONOSUMDB` and `GONOPROXY` alongside GOPRIVATE to ensure Go doesn't try the public checksum database or proxy for nested subgroup paths.
116+
117+
## Troubleshooting
118+
119+
| Error | Cause | Fix |
120+
|-------|-------|-----|
121+
| `410 Gone` | Module proxy can't access private repo | Ensure GOPRIVATE is set correctly |
122+
| `404 Not Found` | Git can't authenticate | Check `.netrc` or SSH config |
123+
| `remote: HTTP Basic: Access denied` | Token expired or wrong scope | Regenerate PAT with `repo` (GitHub) or `read_repository` (GitLab) scope |
124+
| `could not read Username` | Git prompting for credentials in non-interactive mode | Add `.netrc` or SSH config — don't rely on interactive auth in CI/Docker |

quickstart.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -354,6 +354,10 @@ func init() {
354354
{: .warning }
355355
Interceptor configuration functions must be called during `init()` — they are not safe for concurrent use.
356356

357+
## Private Modules
358+
359+
If your service depends on private Go modules, GOPRIVATE is pre-configured in the Makefile, Dockerfile, and CI workflows from the `goprivate` value you set during project creation. You just need to set up authentication for your platform. See the [Private Modules guide](/howto/private-modules/) for GitHub, GitLab, Docker, and CI setup.
360+
357361
## What's Built In (You Didn't Have to Configure)
358362

359363
Everything below was set up automatically by ColdBrew:

tests/navigation.spec.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ const howtoPages = [
2727
"/howto/production/",
2828
"/howto/testing/",
2929
"/howto/workers/",
30+
"/howto/private-modules/",
3031
];
3132

3233
test.describe("Page Loading", () => {

0 commit comments

Comments
 (0)