必须提前在有网机器上用完全相同的Go版本执行go mod download、go mod tidy和go mod vendor,并打包$GOPATH/pkg/mod及vendor目录;离线机需设GOPROXY=direct、GOSUMDB=off,且GOROOT严格为/usr/local/go,构建时显式使用-go build -mod=vendor。

不能在无网服务器上运行 go mod download —— 它会卡死或报 proxy.golang.org: no such host,必须提前在有网机器上完成全部依赖打包。
离线构建前必须预拉取所有模块并禁用校验
即使 go 命令能执行,go build 仍可能失败,典型现象是卡在 verifying github.com/sirupsen/logrus@v1.9.3 或报 checksum mismatch。这不是网络超时,而是 Go 默认仍尝试连接 sum.golang.org。
- 在有网机器上,用**完全相同的 Go 版本**执行:
go mod download -x golang.org/x/net golang.org/x/sysgo mod tidygo mod vendor - 把整个
$GOPATH/pkg/mod目录打包带走(保留结构),同时拷贝项目根目录下的vendor/文件夹 - 在无网机上设环境变量:
go env -w GOPROXY=direct GOSUMDB=off(注意:必须用-w写入)
为什么解压路径必须是 /usr/local/go
/usr/local/go 是 Go 工具链内部默认探测路径,改了容易出问题。错一个字就会报 cannot execute binary file: Exec format error。
- 先在目标机上运行
uname -m确认架构:x86_64→ 下载go1.22.5.linux-amd64.tar.gz;aarch64或arm64→ 必须选go1.22.5.linux-arm64.tar.gz - 解压后执行
/usr/local/go/bin/go version,能输出版本即说明二进制可用 - 别用
wget直接抓链接——可能跳转到镜像页导致下载失效;去https://go.dev/dl/手动下载
环境变量必须写入 /etc/profile.d/ 而非仅 ~/.bashrc
无网服务器常用于部署或 CI 场景,很多工具(如 systemd service、Jenkins agent、cron)启动的是非登录 shell,读不到 ~/.bashrc。只改用户级配置会导致 go 命令在子进程中不可用。
- 创建
/etc/profile.d/golang.sh,内容严格如下(路径不能错):export GOROOT=/usr/local/goexport PATH=$GOROOT/bin:$PATHexport GOPATH=$HOME/goexport PATH=$PATH:$GOPATH/bin - 执行
source /etc/profile.d/golang.sh后,新开终端再运行go env GOROOT,输出必须是/usr/local/go - 若
go install报权限错误,说明$GOPATH/bin不在PATH里,或$GOPATH目录属主不是当前用户
构建时必须用 -mod=vendor 且禁用 CGO
无网环境下,go build 默认仍会尝试访问网络验证 vendor 内容。不加参数会 fallback 到 proxy 请求,直接失败。
- 构建命令必须显式指定:
go build -mod=vendor -ldflags="-s -w" - 若项目含 C 代码(如 sqlite、openssl),需提前在有网机编译好静态库,或设
CGO_ENABLED=0;否则无网机缺少头文件和系统库会报错 -
go mod vendor生成的vendor/必须提交进 Git,且与go.mod和go.sum版本严格对应,否则-mod=vendor会拒绝构建
最易被忽略的是:预拉取依赖时没用和目标机**完全一致的 Go 版本**,或者 go.sum 没同步更新 —— 这会导致无网机上 go build 仍校验失败,且没有任何提示,只静默退出。

















