Go module代理必须启用GO111MODULE=on并配置GOPROXY指向私有服务,否则绕过代理直连;GOPRIVATE需配合处理私有域名模块;Athens需检查端口、存储权限及pseudo-version解析。

Go module proxy 为什么必须用 GO111MODULE=on 和 GOPROXY 环境变量
不设这两个变量,go build 或 go get 默认走 GOPATH 模式或直接拉 GitHub,完全绕过你的私有代理。Athens 或自建 goproxy 服务根本不会被触发。
实操建议:
立即学习“go语言免费学习笔记(深入)”;
-
GO111MODULE=on是硬性前提,哪怕项目在$GOPATH下也得开——Go 1.16+ 虽默认开启,但显式声明更稳 -
GOPROXY必须指向你的服务地址,例如http://localhost:3000(Athens)或http://my-goproxy.internal,不能带尾部斜杠 - 若需 fallback 到官方代理,写成
GOPROXY=http://localhost:3000,https://proxy.golang.org,direct;注意direct表示最后兜底直连,不是跳过验证 - 避免把
GOPROXY设为off——这会禁用所有代理,包括私有和官方的
Athens 启动时常见 failed to listen on :3000 和模块缓存权限问题
Athens 默认监听 :3000,端口被占或没权限是高频报错;另外它默认把模块存到 /var/athens/storage,容器里非 root 用户常因目录不可写而静默失败。
实操建议:
立即学习“go语言免费学习笔记(深入)”;
- 启动前先检查端口:
lsof -i :3000或netstat -tulpn | grep :3000 - 用
-config /path/to/config.toml显式指定配置文件,里面改storage.type = "filesystem"并设storage.filesystem.rootPath = "./storage",避免权限坑 - 别用
docker run -p 3000:3000 gomods/athens就完事——加-v $(pwd)/storage:/var/athens/storage挂载可写目录 - 如果模块拉取后始终 404,检查 Athens 日志里是否有
error="no module found",大概率是 storage 路径没生效或模块名拼写错误(比如github.com/user/repo少了v版本号)
自建 goproxy(如 proxy.golang.org 的轻量替代)如何支持私有域名模块
开源 goproxy(如 goproxy.cn 的 Go 实现)默认只代理公开路径,gitlab.example.com/my/group/pkg 这类私有域名模块会直接 404,不是配置漏了,是设计如此。
实操建议:
立即学习“go语言免费学习笔记(深入)”;
- 必须启用
GOPRIVATE环境变量,例如GOPRIVATE=gitlab.example.com,github.company.com,让 Go 工具链对这些域名跳过代理、改用 git clone -
GOPROXY和GOPRIVATE要配对用:前者管公开模块,后者管私有模块;两者互不覆盖 - 私有模块的
go.mod里module行必须和GOPRIVATE中的域名完全一致(区分大小写,不含路径前缀) - 若私有 Git 服务器需要认证,得配
git config --global url."https://token:x-oauth-basic@github.company.com".insteadOf "https://github.company.com",否则go get会卡在 auth
模块代理上线后 CI/CD 流水线突然拉不到 v0.0.0-xxx 时间戳版本
Go 的 pseudo-version(如 v0.0.0-20230101120000-abcdef123456)依赖 commit time 和 hash,Athens/goproxy 缓存时若未严格按语义化规则解析,可能存错路径或拒绝索引。
实操建议:
立即学习“go语言免费学习笔记(深入)”;
- Athens 需开启
download.mode = "sync"(默认),否则对无 tag 的 commit 可能返回 404 - 确保
go.mod里require行写的是完整 pseudo-version,不要手写成v0.0.0-00010101000000-000000000000这种非法格式 - CI 中执行
go mod download前,确认GOOS/GOARCH和本地一致——不同平台生成的 pseudo-version 可能不同(尤其含 cgo 时) - 查缓存是否命中:直接 curl
http://your-proxy/module/@v/v0.0.0-xxx.info,看返回是否为 200 + JSON;404 说明代理根本没抓到这个版本
真正麻烦的不是搭起来,是模块路径、环境变量、Git 配置三者之间那几处不报错但静默失效的缝隙——多打一次 go env,比重启服务有用。










