Docker中构建Golang项目时遇到$GOPATH或$GOROOT找不到包的问题

Docker中构建Golang项目时遇到$GOPATH或$GOROOT找不到包的问题 我有一个项目路径为 /Users/me/Documents/dev/grafana/src/github.com/grafana/grafana。该项目使用了其他几个项目,例如:

/Users/me/Documents/dev/grafana/src/github.com/BurntSushi/toml
/Users/me/Documents/dev/grafana/src/github.com/Unknwon/com

在我的机器上可以正常构建所有内容,但当我尝试在 Docker 内构建时,出现了一系列 cannot find package 错误。

go install -v ./pkg/cmd/grafana-server
pkg/login/ldap_settings.go:7:2: cannot find package "github.com/BurntSushi/toml" in any of:
/usr/local/go/src/github.com/BurntSushi/toml (from $GOROOT)
/go/src/github.com/BurntSushi/toml (from $GOPATH)
pkg/services/notifications/codes.go:9:2: cannot find package "github.com/Unknwon/com" in any of:
/usr/local/go/src/github.com/Unknwon/com (from $GOROOT)
/go/src/github.com/Unknwon/com (from $GOPATH)

当我自行构建时,我的 $GOPATH=/Users/me/Documents/dev/grafana/——在我的 Dockerfile 中配置如下:

FROM golang:latest AS build

RUN go version

ENV SRC_DIR=/go/src/github.com/grafana/grafana/
ENV GIT_SSL_NO_VERIFY=1

COPY . $SRC_DIR
WORKDIR $SRC_DIR

[... dependency installations ...]

# Building of Grafana
RUN npm run build
RUN go run build.go setup
RUN go run build.go build

我无法理解为什么这个步骤(特别是 RUN go run build.go setup 步骤)一直报告无法访问这些包。

我查阅了类似的问题,但几乎所有相关问题都没有明确说明在 Docker 中构建(而那些涉及 Docker 的对此场景也没有太大帮助)。


更多关于Docker中构建Golang项目时遇到$GOPATH或$GOROOT找不到包的问题的实战教程也可以访问 https://www.itying.com/category-94-b0.html

5 回复

您没有将代码路径 /go/src/github.com/grafana/grafana/ 添加到容器内部。

更多关于Docker中构建Golang项目时遇到$GOPATH或$GOROOT找不到包的问题的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


尝试运行显式的 go get $SRC_DIR/...

func main() {
    fmt.Println("hello world")
}

petkop:

你没有在容器内添加你的代码 /go/src/github.com/grafana/grafana/。

我猜他这样做了:

COPY . $SRC_DIR

是的,我之前没看到。我收回那句话。但我没看到目录被创建。

@calebt

你执行多阶段 Docker 构建的方式不正确,正如 @NobbZ 提到的,请获取你的依赖项。

FROM golang:1.7.3 as builder
WORKDIR /go/src/github.com/alexellis/href-counter/
RUN go get -d -v golang.org/x/net/html  
COPY app.go    .
RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o app .

FROM alpine:latest  
RUN apk --no-cache add ca-certificates
WORKDIR /root/
COPY --from=builder /go/src/github.com/alexellis/href-counter/app .
CMD ["./app"] 

Docker Documentation

使用多阶段构建

多阶段构建是一项新功能,要求 Docker 守护进程和客户端版本为 17.05 或更高。多阶段构建对于任何在优化 Dockerfile 同时保持…方面遇到困难的人都非常有用。

问题在于你的Docker容器中的GOPATH设置与本地环境不匹配。在Dockerfile中,GOPATH默认是/go,但你的项目结构期望GOPATH为/Users/me/Documents/dev/grafana/

解决方案是在Dockerfile中正确设置GOPATH,确保依赖包位于正确的GOPATH/src目录下。以下是修复后的Dockerfile示例:

FROM golang:latest AS build

RUN go version

# 设置正确的GOPATH
ENV GOPATH=/go
ENV SRC_DIR=$GOPATH/src/github.com/grafana/grafana/
ENV GIT_SSL_NO_VERIFY=1

# 复制源代码到GOPATH中的正确位置
COPY . $SRC_DIR
WORKDIR $SRC_DIR

# 确保依赖包在GOPATH中
RUN go get -v github.com/BurntSushi/toml
RUN go get -v github.com/Unknwon/com

# 构建Grafana
RUN npm run build
RUN go run build.go setup
RUN go run build.go build

如果项目使用go.mod,更好的方法是使用Go模块:

FROM golang:latest AS build

RUN go version

WORKDIR /app
COPY . .

# 启用Go模块并下载依赖
ENV GO111MODULE=on
RUN go mod download
RUN go mod verify

# 构建
RUN npm run build
RUN go run build.go setup
RUN go run build.go build

对于使用vendor目录的项目:

FROM golang:latest AS build

RUN go version

ENV GOPATH=/go
ENV SRC_DIR=$GOPATH/src/github.com/grafana/grafana/
COPY . $SRC_DIR
WORKDIR $SRC_DIR

# 使用vendor目录
ENV GOFLAGS="-mod=vendor"
RUN go run build.go setup
RUN go run build.go build

关键点是确保Docker容器中的GOPATH设置与项目结构一致,或者使用Go模块来管理依赖。检查你的项目是否包含go.mod文件,如果存在,使用第二种方法会更简洁可靠。

回到顶部