离线Go项目成功构建只取决于所有模块是否已物理落盘到$GOPATH/pkg/mod/cache/download/目录——必须用一致Go版本在联网机执行go mod download -x预拉取,离线机需设GOPROXY=direct、GOSUMDB=off并验证go list -m all无报错。

离线 Go 项目能成功构建,只取决于一件事:所有模块是否已物理落盘到目标机的 $GOPATH/pkg/mod/cache/download/ 目录下——不是“有没有 go.mod”,也不是“vendor 目录存不存在”,而是 Go 构建时能否在本地缓存中直接命中每个模块的 zip 和校验文件。
go mod download -x 必须在联网且版本一致的机器上执行
离线机上运行 go mod download 一定会失败,报错类似 proxy.golang.org: no such host 或 TLS timeout。这不是配置问题,是 Go 模块机制的设计使然:它默认强依赖网络代理和校验服务。
- 必须用与目标离线环境**完全一致的 Go 版本**(如
go1.21.6)执行预拉取,否则go.sum中的校验和可能不兼容 - 运行
go mod tidy确保go.mod和go.sum完整,尤其检查含// indirect标记的模块是否已被显式require - 执行
go mod download -x,观察终端输出路径,确认所有模块都写入了$GOPATH/pkg/mod/cache/download/(注意不是mod/根目录) - 若项目含
replace github.com/internal/lib => git@xxx:/path,需手动git clone对应仓库,并用go mod edit -replace=github.com/internal/lib=./internal/lib改为相对路径
打包与解压必须保留完整路径结构
只拷贝 download/ 目录本身,不要压缩整个 $GOPATH/pkg/mod;解压位置也必须与源机 $GOPATH 一致,否则 Go 找不到缓存。
- 在联网机打包:
tar -czf gomod-cache.tar.gz -C $GOPATH/pkg/mod/cache download/ - 在离线机解压:
sudo tar -xzf gomod-cache.tar.gz -C $GOPATH/pkg/mod/cache/(注意末尾斜杠) - 验证方式:执行
go list -m all,不报错且输出完整模块列表即表示缓存已就位 - 如果离线机
$GOPATH与源机不同(如源机是/home/user/go,离线机是/opt/go),解压前需先改路径或设GOENV覆盖
GOPROXY=direct + GOSUMDB=off 是离线构建的硬性前提
即使缓存已到位,若没关掉校验和和代理,go build 仍会尝试连 sum.golang.org 或 proxy.golang.org,导致卡住或报 checksum mismatch。
Go 配置库,使用 spf13/viper — 分层优先级(flag > env >file > KV > default),提供 BindPFlag/BindPFlags、SetEnvPrefix + SetEnvKeyReplace 等功能。
立即学习“go语言免费学习笔记(深入)”;
- 必须在离线机上执行:
go env -w GOPROXY=direct(不是off或空值) - 必须执行:
go env -w GOSUMDB=off(设为""仍可能 fallback 到默认值) - 建议加
-mod=readonly参数编译:go build -mod=readonly -o myapp,防止意外触发网络请求 - 不要设
GOPROXY=off——Go 会将其解释为“无代理但允许直连”,仍会尝试解析域名
goproxy 本地文件代理比 vendor 更可靠
go mod vendor 看似简单,但对 replace、indirect 依赖、跨架构构建支持差,且 vendor 后仍需目标机具备 cgo 工具链——这对麒麟、统信等国产系统很不友好。
- 更推荐用
goproxy起本地文件代理:goproxy -proxy=file:///path/to/download -listen=localhost:8080 - 设环境变量:
go env -w GOPROXY=http://localhost:8080,go env -w GOSUMDB=off - 优势在于:保留模块语义、支持私有 replace、便于 CI 复用同一份缓存包、无需修改项目结构
- 注意
file://路径必须指向解压后的download/目录,不是其父级
真正容易被忽略的是:CGO_ENABLED=0 不能解决所有问题——如果项目用了 net 包且启用了 cgo,离线机缺 /etc/resolv.conf 或 libc 头文件,照样 panic;而如果用了 CGO_ENABLED=0,DNS 解析又可能失效。这些底层绑定问题,必须在打包前就验证清楚,而不是等部署时报错才去查。

















