无网环境下Go模块依赖能跑起来的前提是:所有依赖必须提前在有网机完整缓存或vendor化,且GOPROXY=off、GOSUMDB=off已设;go version失败多因二进制架构不匹配,需按uname -m结果下载对应linux-amd64或linux-arm64包并解压至/usr/local/go;GO111MODULE=on必须显式启用,离线构建仅支持vendor或pkg/mod一种路径,不可混用。

无网环境下 Go 模块依赖能跑起来,前提是所有依赖已提前完整缓存或 vendor 化,且 GOPROXY 和 GOSUMDB 被正确设为离线模式。直接在无网机上执行 go mod download 必然失败,报 proxy.golang.org: no such host 或卡死。
确认 Go 二进制本身能在目标机运行
很多“无网构建失败”其实卡在第一步:go version 都执行不了。根本不是依赖问题,而是二进制格式不匹配。
- 先在目标服务器运行
uname -m:输出x86_64→ 必须下载linux-amd64.tar.gz;输出aarch64或arm64→ 必须选linux-arm64.tar.gz - 解压路径必须是
/usr/local/go,这是 Go 工具链硬编码探测路径,改了会导致go env GOROOT返回空或错误 - 验证命令:
/usr/local/go/bin/go version能输出版本号,才算二进制就绪
GO111MODULE=on 是模块可用的前提
即使 go version 正常,go mod init 仍可能静默失败或报 no modules found——这几乎一定是 GO111MODULE 没开。
-
GO111MODULE=auto在无网机上极不可靠:它依赖当前路径是否在$GOPATH/src下判断是否启用模块,而离线环境往往路径随意 -
GO111MODULE=off会彻底禁用模块机制,go mod命令全部失效,go get也不写go.mod - 唯一稳妥做法:
go env -w GO111MODULE=on,然后go env GO111MODULE输出必须是on
离线依赖的两种可靠路径:vendor 或 pkg/mod 缓存
不能指望“边连边下”,必须选一种方式把依赖提前带进来。二者互斥,别混用。
Go 配置库,使用 spf13/viper — 分层优先级(flag > env >file > KV > default),提供 BindPFlag/BindPFlags、SetEnvPrefix + SetEnvKeyReplace 等功能。
立即学习“go语言免费学习笔记(深入)”;
-
用
vendor/:在有网机项目根目录执行go mod vendor,打包整个vendor/目录到无网机;然后在无网机设go env -w GOPROXY=direct GOSUMDB=off,构建时加-mod=vendor参数(go build -mod=vendor) -
用
$GOPATH/pkg/mod缓存:在有网机用相同 Go 版本执行go mod download,打包整个$GOPATH/pkg/mod目录;无网机解压后设go env -w GOPROXY=off GOSUMDB=off,之后go build会自动从本地缓存读取 - 注意:
go mod vendor生成的vendor/modules.txt不能手动改,它是工具自维护的元数据
私有模块和 checksum 校验必须显式关掉
即便依赖文件都在本地,go build 仍可能报 checksum mismatch 或卡在 verifying xxx ——这是 Go 默认仍尝试连接 sum.golang.org 校验。
-
GOSUMDB=off必须设置,否则校验失败直接中断构建;这不是可选项,是离线必需 - 如果项目含私有仓库(如
git.internal.company.com/lib),还必须配go env -w GOPRIVATE="git.internal.company.com",否则 Go 会试图用GOPROXY去拉私有地址,返回 401 或 404 -
GOPROXY=off和GOPROXY=direct效果不同:off完全禁用代理逻辑,direct表示“找不到才回源”,但离线时回源必挂,所以优先选off
最容易被忽略的是:go mod vendor 后没删掉 replace 指令,或者 pkg/mod 缓存没覆盖 transitive 依赖。离线环境没有重试机会,每一步都得在有网机验证完整——比如运行 go list -m all 看是否所有依赖都列出来了,再检查 go.mod 里有没有漏掉的 require。

















