离线编译失败主因是模块机制默认联网,必须设GOPROXY=direct、GOSUMDB=off、GO111MODULE=on,并配合go build -mod=vendor显式启用vendor目录,否则即使有vendor/仍会悄悄联网校验。

离线编译失败,八成不是 Go 安装问题,而是模块机制仍在尝试联网——go build 默认会查 proxy.golang.org 和 sum.golang.org,哪怕你本地有 go.mod 和 vendor/。必须显式切断这两条通路,否则进程卡在 “Fetching…” 无报错、无超时。
离线构建前必须设死的三个环境变量
不设这三项,go build 就算有 vendor/ 也会悄悄联网校验或 fallback 到代理。
-
GOPROXY=direct:跳过所有代理,强制从本地路径(如vendor/或$GOPATH/pkg/mod)读模块,但不发起任何 HTTP 请求 -
GOSUMDB=off:关闭校验和检查,否则go build会因无法连接sum.golang.org而阻塞或报checksum mismatch -
GO111MODULE=on:确保模块模式启用;老项目若没go.mod,设auto可能导致行为不一致,统一设on更可控
vendor/ 目录必须配合 -mod=vendor 才生效
很多人把 vendor/ 目录拷过去就以为万事大吉,结果 go build 仍报 cannot find module——因为 vendor 不是默认启用的,它只是个快照目录。
Go 配置库,使用 spf13/viper — 分层优先级(flag > env >file > KV > default),提供 BindPFlag/BindPFlags、SetEnvPrefix + SetEnvKeyReplace 等功能。
- 构建命令必须显式加参数:
go build -mod=vendor,否则 Go 工具链无视vendor/,仍走模块缓存路径 -
go test、go install同样要加-mod=vendor,CI 中漏掉一个就会失败 -
go mod vendor不会自动更新go.sum,离线前需运行go mod verify或go build -mod=readonly确保校验和一致 - 若
go.mod里有replace指向本地路径(如./internal/lib),go mod vendor默认忽略它,得先用go mod edit -replace改为相对路径再 vendor
离线机上验证是否真离线
别只看有没有报错。真正离线意味着整个构建过程不触发任何 DNS 查询或 TCP 连接。
立即学习“go语言免费学习笔记(深入)”;
- 执行
go list -m all:应快速输出全部模块,无卡顿、无no such host类错误 - 用
strace -e trace=connect,socket,dns go build -mod=vendor(Linux)观察是否出现网络系统调用 - 注意
CGO_ENABLED=0不等于完全离线——如果代码用了net.LookupIP,纯 Go DNS 实现不读/etc/resolv.conf,可能连内网 DNS 都解析失败 - 交叉编译产物在目标机器报
not found,大概率是CGO_ENABLED=1导致动态链接了宿主机 libc,而非网络问题
最易被忽略的是 go.sum 文件的换行符和空格——Windows 编辑器保存的 CRLF 或末尾空格会导致校验失败,且错误信息模糊,直接表现为 verifying xxx: checksum mismatch,而不是“找不到文件”。

















