goprivate必须正确设置,否则go mod不会直连gitlab;它默认将所有域名视为公开模块并优先查询goproxy(如proxy.golang.org),导致私有仓库因不在公共索引中而返回404或超时。

GOPRIVATE 必须设对,否则 go mod 根本不会尝试直连你的 GitLab
go mod 为什么连不上 gitlab.example.com?
不是网络不通,也不是 SSH 密钥没配好,而是 Go 工具链压根没发起请求——它默认把所有域名都当成公开模块,先扔给 GOPROXY(比如 https://proxy.golang.org)去查。私有 GitLab 不在公共索引里,代理直接返回 404 或超时,go mod tidy 就卡住或报 no matching versions for query "latest"。
-
GOPRIVATE是唯一能告诉 Go “这个域名别走代理,自己用 git clone”的开关 - 只写
gitlab.example.com不够稳妥;推荐用通配符*.example.com,覆盖api.example.com、gitlab.example.com等所有子域 - 不能写进
.env文件靠direnv加载——go命令不读它,必须是 shell 环境变量
HTTPS + Basic Auth 场景下怎么填账号密码?
如果你的 GitLab 前面还套了一层 Nginx Basic Auth(浏览器弹灰色登录框),go 命令会尝试用 ~/.netrc(Windows 是 %USERPROFILE%\_netrc)读凭据,但格式和位置极其敏感:
- 文件名必须是
_netrc,不能带后缀(如_netrc.txt) - 内容严格按三行写:
machine git.example.com、login your-nginx-user、password your-nginx-pass(注意:不是 GitLab 账号,是 Nginx 层的认证账号) - 验证是否生效:运行
curl --netrc-file "$HOME/.netrc" -v https://git.example.com/project?go-get=1,看到Server auth using Basic和200 OK才算对
为什么 go mod 总是走 git:// 协议而不是 HTTPS?
Go 解析到 <meta name="go-import"> 后,会提取其中的 VCS URL 并执行 git clone。如果 meta 里写的是 git:// 或 ssh://,而你本地没配 SSH,就会报 Permission denied (publickey) 或连接超时。
- 解决办法是让 Git 自动重写协议:
git config --global url."git@git.example.com:".insteadOf "https://git.example.com/" - 必须同时确保
git ls-remote git@git.example.com:group/repo.git能成功返回 refs,否则重写无效 - 如果 GitLab 只开放 HTTPS,那就反向配置:
git config --global url."https://token:x-oauth-basic@git.example.com/".insteadOf "https://git.example.com/"(token 是 GitLab 的 Personal Access Token)
GOPRIVATE 设置顺序和配套变量
GOPRIVATE 生效的前提是它比 GOPROXY 更早被读取。如果先设 GOPROXY=https://proxy.golang.org,direct 再设 GOPRIVATE,Go 仍可能先走代理失败再 fallback,导致错误延迟暴露。
- 正确顺序:先
go env -w GOPRIVATE=*.example.com,再go env -w GOPROXY=https://goproxy.cn,direct - 配套建议显式设
GONOPROXY和GONOSUMDB,避免某些旧版本 Go 在GOPRIVATE未完全生效时漏判 - CI 环境(如 GitHub Actions)必须在 job 的
env:块里声明,不能依赖 runner 默认环境
最容易被忽略的是:Git 的 insteadOf 配置只影响 git 命令行为,而 go mod 是否走 HTTPS 还取决于 GitLab 页面返回的 go-import meta 标签内容。如果标签里写的是 ssh://,哪怕你本地 Git 配了重写,Go 仍会先按那个 URL 尝试——所以最终得看 GitLab 服务端是否正确生成了 meta 标签,或者你是否在项目根目录手动加了 go.mod 中的 replace 指向 HTTPS 地址。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!











