Golang如何在离线环境管理模块依赖

14次阅读

离线环境应设置goproxy=file:///path/to/goproxy并启用GOSUMDB=off。需先在线用go mod download -json导出依赖,按Path/Version结构复制.info/.mod/.zip到本地目录,确保路径绝对、无符号链接,再在离线机配置对应环境变量。

Golang如何在离线环境管理模块依赖

离线环境无法访问 proxy.golang.org 怎么办

Go 模块依赖默认通过 proxy.golang.org(或配置的 GOPROXY)拉取,离线时会直接报错:go: github.com/some/pkg@v1.2.3: Get "https://proxy.golang.org/...": dial tcp: lookup proxy.golang.org: no such host。这不是网络超时,而是 DNS 解析失败 + 无 fallback 代理路径导致的硬性中断。

核心思路是:**绕过远程代理,改用本地文件系统作为模块源**。Go 原生支持 file:// 协议的 GOPROXY,且 go mod download 可导出完整依赖快照。

用 go mod download –json 导出所有依赖到本地目录

在线机器上必须先完成依赖解析和下载,再打包带走。关键不是简单复制 pkg/mod,而是用 Go 工具链生成可移植的模块存档。

  • 确保项目 go.mod 已正确初始化,且 GO111MODULE=on
  • 运行
    go mod download -json > deps.json

    ,它会输出每个模块的 PathVersionSumDir(本地缓存路径)

  • 根据 deps.json 中的 Dir 字段,批量复制对应模块文件夹到一个干净目录(如 ./goproxy),结构保持为 ./goproxy/github.com/user/repo/@v/v1.2.3.info.mod.zip
  • 最终目录需满足:任意模块 github.com/a/bv1.2.3 版本,其文件必须位于 ./goproxy/github.com/a/b/@v/v1.2.3.zip(及同级 .info/.mod)

离线机器上设置 GOPROXY=file:///path/to/goproxy

离线机器无需安装额外服务,Go 自动识别 file:// 路径并按规范查找文件。但路径必须绝对且可读,且不能有符号链接跳转(Go 1.18+ 对 symlink 更严格)。

立即学习go语言免费学习笔记(深入)”;

  • linux/macOS:
    export GOPROXY=file:///home/user/my-goproxy
  • windows
    $env:GOPROXY="file:///C:/my-goproxy"

    (注意三个斜杠,盘符后是正斜杠)

  • 验证是否生效:
    go env GOPROXY

    应输出 file:///...,而非 https://...direct

  • 首次运行 go buildgo mod tidy 时,Go 会从该目录匹配并解压 .zip,不联网

常见坑:sumdb 校验失败与 replace 的干扰

即使代理指向本地,Go 仍默认校验 checksum(通过 sum.golang.org)。离线时会卡住或报 verifying github.com/x/y@v1.2.3: checksum mismatch

  • 必须同时关闭 sumdb:
    export GOSUMDB=off

    (或 GOSUMDB=0

  • 检查 go.mod 是否含 replace 指向本地路径(如 replace example.com => ./local)——离线时这些路径若不存在,go build 会直接失败,需提前注释或改用 replace 指向已打包进 goproxy 的版本
  • 如果项目用了私有 Git 仓库(如 git.internal.com),在线导出时需确保该域名能被解析,否则 go mod download 会失败;建议先用 go mod edit -replace 临时替换为公开 tag,再导出

最易忽略的是 GOSUMDB=off ——很多人只改了 GOPROXY,却卡在校验环节,错误信息里完全不提 sumdb,只显示“checksum mismatch”,实际根本没去读本地文件。

text=ZqhQzanResources