goprivate 必须设置,否则 go 1.13+ 默认通过 proxy.golang.org 拉取模块,私有域名不匹配白名单将导致 403 或仓库未找到;它告诉 go 对指定域名跳过代理和 checksum 校验,直接 git clone。

GOPRIVATE 为什么必须设,不设就拉不到私有模块
Go 在 1.13+ 默认启用代理(GOPROXY=https://proxy.golang.org,direct),所有 go get 都先走公共代理;私有仓库域名(比如 git.example.com)不在白名单里,Go 就不会绕过代理直连,结果就是 403 或 repository not found —— 它根本没发请求到你的 Git 服务器。
设 GOPRIVATE 的作用,就是告诉 Go:“这些域名下的模块,别走代理,也别校验 checksum,直接用 git 命令 clone”。
常见错误现象:
go get git.example.com/myorg/mypkg: module git.example.com/myorg/mypkg: reading https://proxy.golang.org/git.example.com/myorg/mypkg/@v/list: 403 Forbidden- 本地
git clone能通,但go get报unknown revision
怎么设 GOPRIVATE:域名匹配规则比想象中严格
它只做前缀匹配,不支持通配符或正则。比如设成 GOPRIVATE=git.example.com,能覆盖 git.example.com/myorg/mypkg,但覆盖不了 sub.git.example.com/mypkg。
立即学习“go语言免费学习笔记(深入)”;
实操建议:
- 多个域名用逗号分隔,**不能有空格**:
GOPRIVATE=git.example.com,github.mycompany.com - 如果用子域名,每个都要列全:
GOPRIVATE=git.example.com,dev.git.example.com - 本地开发用
localhost或127.0.0.1?必须显式加上:GOPRIVATE=localhost:3000,127.0.0.1:3000 - 想匹配所有非公开域名?可以设
GOPRIVATE="*",但仅限测试环境——它会禁用所有模块的校验,生产慎用
光设 GOPRIVATE 不够:Git 凭据还得自己管
GOPRIVATE 只解决“是否走代理”,不解决“能不能 clone 下来”。私有 Git 仓库通常要 SSH 密钥或 HTTPS token,而 Go 调用的是系统 git 命令,所以凭据得由 git 自己处理。
常见错误场景:
- HTTPS 私仓报
fatal: could not read Username for 'https://git.example.com': No such device or address - SSH 私仓报
permission denied (publickey),但ssh -T git@git.example.com是通的
实操建议:
- HTTPS 方式:配置 git 凭据助手(如
git config --global credential.helper store),然后手动git clone一次触发登录 - SSH 方式:确保
~/.ssh/config里为对应域名配了Host和IdentityFile,且私钥没密码或已用ssh-agent加载 - 别依赖
GOINSECURE:它只对 HTTP(非 HTTPS)仓库生效,且已废弃,新版 Go 会忽略
CI/CD 里容易漏掉的三件事
本地设好了,CI 流水线跑 go build 还失败?大概率是环境没继承或凭据没注入。
关键检查点:
- CI 脚本里没 export
GOPRIVATE,或者用了env:但没传进 job 的 shell 环境 - CI runner 没预装 git,或 git 版本太老(
go mod依赖 git 2.10+ 的某些功能) - 用 GitHub Actions 时,
actions/checkout默认不带 submodule,而你的私有模块可能被当作 submodule 引入——得加submodules: true
最常被忽略的一点:Go 的模块缓存($GOPATH/pkg/mod)在 CI 中是跨 job 复用的。如果上一个 job 用错的 GOPRIVATE 拉过部分模块,新 job 即使改对了,也可能因缓存残留继续失败——加一步 go clean -modcache 更稳妥。










