离线安装Go依赖必须在联网机预拉取全部模块至$GOPATH/pkg/mod/cache/download/并设GOPROXY=direct、GOSUMDB=off,否则go mod download在离线机必报proxy.golang.org: no such host;vendor不等于真离线,需go mod tidy后验证modules.txt与go.sum完全匹配。

go mod download 在离线机上根本不会工作——它默认要连 proxy.golang.org,报错一定是 proxy.golang.org: no such host 或 timeout。离线安装模块不是“在断网机器上运行命令”,而是在有网机器上**提前打包好全部依赖路径和校验数据**,再拷过去。
必须在联网机上执行 go mod download 并确认落盘位置
离线依赖的核心是 $GOPATH/pkg/mod/cache/download/ 目录下的所有内容,不是 go.mod 里列出来的模块名,而是实际下载下来的归档包(.zip)和校验文件(.info、.mod、.zip.hash)。
- 用与目标环境**完全一致的 Go 版本**(如
go1.24.5)执行:go mod download -x,观察输出中所有GET请求对应的本地路径 - 重点确认是否拉取了
golang.org/x/系列(如golang.org/x/net、golang.org/x/sys),它们不随 Go 安装包自带,但很多标准库扩展依赖它们 - 如果项目用了
replace指向私有 Git 地址,go mod download不会处理——必须手动git clone对应仓库,并用go mod edit -replace=xxx=./path/to/local改为本地路径 - 执行完后检查
$GOPATH/pkg/mod/cache/download/是否非空,且目录结构形如github.com/xxx/yyy/@v/v1.2.3.zip
GOPROXY=direct 和 GOSUMDB=off 缺一不可
离线机上只设 GOPROXY=off 是错的——Go 会 fallback 到默认值;只设 GOSUMDB="" 也不行,它仍可能尝试连接 sum.golang.org。
- 正确写法是:
go env -w GOPROXY=direct(不是off,也不是空字符串) - 同时必须:
go env -w GOSUMDB=off(明确关闭校验,否则go build会在 verify 阶段卡住) - 这两个变量必须对所有 shell 会话生效:写入
/etc/profile.d/golang.sh,而不是仅当前终端临时 export - 验证方式:
go env GOPROXY GOSUMDB输出应为direct和off,不能是空或默认地址
go mod vendor 不等于真离线,还要防间接依赖漏掉
vendor/ 目录看起来完整,但 go build 仍可能去 $GOPATH/pkg/mod 查间接依赖或校验和——尤其当 go.sum 里有未被 vendor/modules.txt 覆盖的条目时。
- 执行顺序必须是:
go mod tidy→go mod vendor→diff vendor/modules.txt go.sum | wc -l,输出应为 0 -
go mod vendor不处理replace的本地模块,那些代码必须真实存在于项目内(如./internal/mylib),不能只靠 replace 声明 - 若依赖含 cgo(比如
sqlite3),vendor无法解决底层 C 库缺失问题——离线机仍需装gcc、libc6-dev等,或提前静态编译好二进制并replace进来
验证是否真离线:别信“没报错”,要看 DNS 请求
真正离线意味着从 go mod download(如果你在离线机上误跑)到 go build 全程不发出任何 DNS 查询。光看终端没报错没用,得抓包或关 DNS 测试。
立即学习“go语言免费学习笔记(深入)”;
- 最简验证法:拔网线 +
systemd-resolved或dnsmasq停服务,再跑go build—— 如果卡在 “resolving” 或 “lookup” 就说明还有地方没关干净 - 常见漏点:
CGO_ENABLED=1时net包会读/etc/resolv.conf并尝试解析域名;replace里的私有地址若没改成本地路径,go list仍会尝试解析 - 交叉编译时更危险:
GOOS=linux GOARCH=arm64 go build若没设CGO_ENABLED=0,构建过程可能触发目标平台的 DNS 解析逻辑
GOPROXY=direct 关请求,GOSUMDB=off 关校验,vendor/modules.txt 对齐 go.sum,replace 彻底本地化——少一个,就可能在某个隐式调用路径里突然弹出域名解析失败。


















