Golang离线环境下使用go mod tidy的解决方案

Golang离线环境下使用go mod tidy的解决方案 你好!我的开发环境设置在一个虚拟机中,该虚拟机位于代理之后,目前没有互联网连接。运行 go mod tidy 时出现错误:

github.com/ishidawataru/sctp: Get "https://proxy.golang.org/github.com/ishidawataru/sctp/@v/list": proxyconnect tcp: dial tcp 10.250.110.36:8000: connect: connection refused

如果我能在其他地方下载包的源文件,并将它们放在 ~/go/pkg/mod 下的正确目录中,或者使用 go mod vendor,是否可行?


更多关于Golang离线环境下使用go mod tidy的解决方案的实战教程也可以访问 https://www.itying.com/category-94-b0.html

5 回复

实际上,我无法将我的代码从虚拟机迁移到另一个能访问互联网的Ubuntu环境。我的团队正在努力解决这个问题,但这需要一些时间。

更多关于Golang离线环境下使用go mod tidy的解决方案的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


您可以尝试在其他地方使用 go mod vendor,然后将其移动到您的项目中。或者,作为替代方案,您可以尝试使用工作区。

这里有一些可能有用的讨论:

https://www.reddit.com/r/golang/comments/pxuhyb/go_mod_tidy_problem/

不过,你为什么要在你的虚拟机中运行 go mod tidy 呢?你完全可以在能访问互联网的机器上运行它,然后将整理好的 go.modgo.sum 文件推送到你的虚拟机。

你能在将代码推送到离线虚拟机之前执行 go mod vendortidy 吗?关键在于:如果你想使用来自互联网的依赖项,那么在你的工具链中的某个环节,你将需要互联网连接。如果你想获取那些尚未在代码中使用(但你知道将来会需要)的依赖项,你可以按照这个要点中的建议进行导入/供应商化处理:

import (
	_ "github.com/gorilla/mux"
	_ "github.com/sirupsen/logrus"
)

因此,添加所有你已知将来会需要的外部导入,对它们执行 go mod vendor,然后将结果推送到你的离线虚拟机。

在离线环境下使用 go mod tidy 确实会遇到网络连接问题。以下是几种可行的解决方案:

方案一:使用 vendor 目录(推荐)

  1. 在联网环境中生成 vendor 目录:
# 在可联网的机器上
go mod vendor
  1. 将整个项目(包括 vendor 目录)复制到离线环境:
# 项目结构
your-project/
├── go.mod
├── go.sum
├── main.go
└── vendor/          # 所有依赖包都在这里
  1. 在离线环境中使用 vendor 模式:
# 设置使用 vendor 目录
go env -w GOFLAGS="-mod=vendor"

# 或者每次运行命令时指定
go mod tidy -mod=vendor
go build -mod=vendor

方案二:手动下载依赖包到 GOPATH/pkg/mod

  1. 在联网环境中下载依赖:
# 下载所有依赖到 GOPATH
go mod download

# 或者下载特定模块
go mod download github.com/ishidawataru/sctp@latest
  1. 复制 GOPATH/pkg/mod 目录到离线环境:
# 在联网环境找到模块缓存目录
go env GOMODCACHE
# 通常是 ~/go/pkg/mod

# 将整个目录复制到离线环境的相同位置
  1. 在离线环境中设置 GOPROXY 为 direct:
# 禁用代理,直接从模块缓存读取
go env -w GOPROXY=direct
go env -w GOSUMDB=off

方案三:使用 replace 指令(临时解决方案)

go.mod 文件中添加本地路径替换:

module your-project

go 1.21

require (
    github.com/ishidawataru/sctp v0.0.0-20210707010723-9a39160e9062
)

replace github.com/ishidawataru/sctp => ../local-sctp  # 本地路径

方案四:创建本地模块代理

  1. 在联网环境搭建 Athens 代理并缓存模块:
# 使用 Athens 创建本地代理服务器
docker run -d -p 3000:3000 \
  -v /path/to/cache:/var/lib/athens \
  gomods/athens:latest
  1. 在离线环境使用本地代理:
# 设置使用本地代理服务器
go env -w GOPROXY=http://localhost:3000
go env -w GOSUMDB=off

完整示例:使用 vendor 方案

# 在联网环境准备项目
mkdir myproject && cd myproject
go mod init example.com/myproject

# 添加依赖
go get github.com/ishidawataru/sctp

# 创建 vendor 目录
go mod vendor

# 复制整个项目到离线环境后:
cd /offline/myproject

# 方法1:设置全局使用 vendor
go env -w GOFLAGS="-mod=vendor"
go mod tidy  # 现在会使用 vendor 目录

# 方法2:临时使用 vendor
go mod tidy -mod=vendor
go build -mod=vendor

# 方法3:使用 vendor 并禁用网络检查
GOPROXY=off go mod tidy -mod=readonly

注意事项

  1. 版本一致性: 确保联网和离线环境的 Go 版本相同
  2. 完整复制: 复制时需要包含 go.modgo.sumvendor 目录
  3. 平台兼容性: 如果开发环境跨平台,注意依赖包的平台特异性

对于完全离线的环境,方案一(vendor)是最可靠的选择,因为它将所有依赖打包在项目中,不依赖任何外部网络或代理。

回到顶部