Featured image of post 使用 docker build 时 下载 golang.org/x 包失败

使用 docker build 时 下载 golang.org/x 包失败

前言

在我们使用 go getgo installgo mod 等命令时,会自动下载相应的包或依赖包。
但由于众所周知的原因,类似于 golang.org/x/... 的包会出现下载超时。

如下所示:

1
2
$ go get -u golang.org/x/sys
$ go get golang.org/x/sys: unrecognized import path "golang.org/x/sys" (https fetch: Get https://golang.org/x/sys?go-get=1: dial tcp 216.239.37.1:443: i/o timeout)

在开发的时候我们可以去 github 上找相应的包直接下载到本地,把包 copy 到 $GOPATH golang.org/x 下就可以。

但是使用 docker build 时,docker 不会从本地去拉取这个包,虽然可以把包打在项目中解决,但可能会逼死强迫症吧。

解决方式

直接下载包

这里只沾地址〜 不做解释.

https://github.com/golang

go mod replace

从 Go 1.11 版本开始,新增支持了 go modules 用于解决包依赖管理问题。
该工具提供了 replace,就是为了解决包的别名问题,也能替我们解决 golang.org/x 无法下载的的问题。

go module 被集成到原生的 go mod 命令中,但是如果你的代码库在 $GOPATH 中,module 功能是默认不会开启的,想要开启也非常简单,通过一个环境变量即可开启 export GO111MODULE=on

如果是使用 docke build,只需要在 Dockerfile 中添加

1
ENV GO111MODULE=on

使用 models replace

1
2
3
4
5
6
7
module example.com/hello
require (
    golang.org/x/text v0.3.0
)
replace (
    golang.org/x/text => github.com/golang/text v0.3.0
)

设置代理 GOPROXY

我们知道从 Go 1.11 版本开始,官方支持了 go module 包依赖管理工具。

其实还新增了 GOPROXY 环境变量。如果设置了该变量,下载源代码时将会通过这个环境变量设置的代理地址,而不再是以前的直接从代码库下载。

goproxy.io 这个开源项目帮我们实现好了我们想要的。该项目允许开发者一键构建自己的 GOPROXY 代理服务。同时,也提供了公用的代理服务 https://goproxy.io,我们只需设置该环境变量即可正常下载被墙的源码包了:

export GOPROXY=“https://goproxy.io

Dockerfile 中添加

1
ENV GOPROXY="https://goproxy.io"

不过,需要依赖于 go module 功能。需要同时开启 GO111MODULE 和 设置 GOPROXY

Dockerfile

1
2
3
# ENV 设置环境变量
ENV GOPROXY="https://goproxy.io"
ENV GO111MODULE=on
  • 参考: https://mp.weixin.qq.com/s/COethtOaiygsYev-kkCc4A
  • 参考: https://shockerli.net/post/go-get-golang-org-x-solution