离线Golang环境搭建需两步:有网机执行go mod download预拉取模块并同步$GOPATH/pkg/mod,离线机设GOPROXY=direct且GOSUMDB=off;私有模块须配GOPRIVATE,Docker构建推荐go mod vendor固化依赖。

不能直接在无公网服务器上执行 go get 或 go mod download —— 这些命令默认会连接 proxy.golang.org 和 sum.golang.org,失败是必然的。
离线服务器必须预拉取模块缓存并设 GOPROXY=direct
Go 工具链在无网时仍会尝试校验、解析远程路径、查询 checksum,不是“没网络就跳过”,而是卡住或报错 verifying github.com/xxx: Get "https://sum.golang.org/..."。关键动作是两步:在有网机器完整拉取 + 在离线机禁用所有远程行为。
- 在有网机器进入项目根目录,确认
go.mod和go.sum已提交且稳定(不要含未git add的本地修改) - 运行
go mod download(不带-u、@latest等触发远程查询的参数),它会把全部依赖写入$GOPATH/pkg/mod目录 - 打包整个
$GOPATH/pkg/mod(保留原始目录结构),拷贝到离线服务器相同$GOPATH路径下 - 离线机上执行
go env -w GOPROXY=direct GOSUMDB=off—— 注意必须用-w写入,临时 export 不生效
go build 报 missing module 但文件明明存在?检查 go.sum 和路径一致性
缓存目录放对了,go build 却说找不到模块,大概率不是路径问题,而是校验机制被触发后拒绝加载。Go 不仅看文件是否存在,还核对 go.sum 中记录的哈希与缓存内容是否一致。
- 先确认离线机上的
go.sum是从有网机器同步过来的,且未被编辑器自动换行(Windows CRLF 会导致哈希不匹配) - 检查
go.sum对应模块行末是否有空格、tab 或不可见字符 —— 可用xxd go.sum | grep -A1 "module-name"查看十六进制 - 若确定缓存内容可信,可临时绕过:用
go build -mod=readonly -modcacherw,但仅限调试,上线前必须修复go.sum - 不要运行
go clean -modcache—— 它会清掉你手动拷来的全部缓存
私有 Git 模块在离线环境无法解析?GOPRIVATE 必须显式配置
即使设了 GOPROXY=direct,Go 默认仍会对私有域名(如 git.internal.company/mylib)尝试走代理校验,除非明确告诉它“这是私有的,别转发”。否则会报 unrecognized import path 或 401 Unauthorized。
立即学习“go语言免费学习笔记(深入)”;
- 在有网机器拉取私有模块时,就要确保其
go.mod第一行 module 声明与实际克隆 URL 完全一致(含端口、协议、大小写) - 离线机上执行
go env -w GOPRIVATE=git.internal.company,*.corp.internal(逗号分隔,不带https://) - 如果私有 Git 服务用 HTTP(非 HTTPS),还需加
GOINSECURE=git.internal.company - 若用自签名证书,Go 1.21+ 需设
GOTRUST=1;更稳妥的是把证书导入系统信任库,避免工具链层绕过
Docker 构建阶段也断网?go mod vendor 是最稳的方案
CI/CD 或容器构建中,go build 阶段意外触发网络请求是高频翻车点。哪怕设置了 GOPROXY=direct,某些 Go 版本或依赖仍可能隐式访问远程地址。唯一彻底隔离网络的方式是把依赖固化进代码树。
- 在有网机器运行
go mod vendor,生成vendor/目录(含所有依赖源码和vendor/modules.txt) -
Dockerfile中,COPY go.mod go.sum .必须放在COPY . .之前,否则构建缓存失效 - 紧接着
RUN go mod download—— 此时因go.mod已存在,该命令只校验 vendor 内容,不联网 - 最后加
ENV GOFLAGS=-mod=vendor,强制后续所有go命令只读vendor/,完全忽略go.mod中的远程路径
真正麻烦的从来不是“怎么拷文件”,而是 go.sum 哈希、GOPRIVATE 域名拼写、vendor/ 目录是否被 .gitignore 排除、以及 Docker 构建顺序里那几行看似无关紧要的 COPY 位置 —— 这些细节错一个,构建就会在最后一秒失败。


















