go build在Docker上无法找到本地依赖项。

huangapple go评论89阅读模式
英文:

go build fails to find local dependencies on docker

问题

我正在尝试为我的Go服务器创建一个Dockerfile,但是它一直失败,因为它无法识别一些本地依赖项(它们是代码本身的模块,而不是外部依赖项)。

例如:

import (
	"<private-repo-url>/src/cmd/http-api/bootstrap" // 这是服务器的本地模块
	"go.uber.org/fx"
)

func main() {
	fx.New(bootstrap.Module).Run()
}

这是错误信息:

 => ERROR [7/7] RUN go build -a -o ./server                                                                                                                                                                        0.3s
------
 > [7/7] RUN go build -a -o ./server:
#10 0.295 server.go:4:2: no required module provides package <private-repo-url>/src/cmd/http-api/bootstrap; to add it:
#10 0.295       go get <private-repo-url>/src/cmd/http-api/bootstrap
------
executor failed running [/bin/sh -c go build -a -o ./server]: exit code: 1

请注意,这里的private-repo-url对应于该应用程序的存储库(它不是外部依赖项)。

以下是Dockerfile的内容:

FROM golang:1.17

WORKDIR /balrog

# 复制依赖定义并下载它们
ADD go.mod .
ADD go.sum .
RUN go mod download

# 构建二进制文件
ADD ./src .
ENV CGO_ENABLED=0
ENV GOOS=linux
ENV GOARCH=amd64
RUN go build -a -o ./server

# 运行服务器
CMD ["/server"]

还有mod.go文件:

module <private-repo-url>

go 1.16

require (
	github.com/gin-gonic/gin v1.7.7
	github.com/google/uuid v1.3.0
	github.com/kelseyhightower/envconfig v1.4.0
	github.com/sirupsen/logrus v1.8.1
	go.uber.org/fx v1.15.0
)

我已经阅读了关于GO111MODULE的内容,它应该是on,我还读到从1.17版本开始默认启用它(这里)。

根据官方的Docker镜像(在dockerhub中),正确的方法是在复制所有文件之后使用go getgo install。这种方法导致了一个稍微不同的问题,即Docker无法访问存储库(因为它是私有的),而我希望避免将凭据添加到Docker中。

我尝试了一下环境变量GOVCS,将其值设置为:

ENV GOVCS=github.com:git,gitlab.com:off

但它仍然以相同的错误失败。

最后,我尝试了替换操作,我发现如果我从本地依赖项中删除<private-repo-url>,它就可以工作,所以我在Dockerfile中执行了以下操作:

RUN go mod edit -replace <private-repo-url>=./

但它仍然失败,并显示以下错误:

 => ERROR [builder 10/10] RUN go build -a -o ./server                                                                                                                                                              0.3s
------
 > [builder 10/10] RUN go build -a -o ./server:
#17 0.299 server.go:4:2: module <private-repo-url>/src provides package <private-repo-url>/src/cmd/http-api/bootstrap and is replaced but not required; to add it:
#17 0.299       go get <private-repo-url>/src
#17 0.299 server.go:5:2: no required module provides package go.uber.org/fx; to add it:
#17 0.299       go get go.uber.org/fx

有没有办法阻止Go构建器/包安装程序在外部查找这些文件?因为go modgo get + go install都尝试访问这个私有存储库,并且由于它们没有访问权限,所以失败了。但是它们不应该在第一次尝试时访问它,因为它是应用程序的存储库...或者是我做错了什么(显然,否则我就不会在这里了),有什么遗漏的地方吗?

英文:

I'm trying to create a dockerfile for my go server but it keeps failing as it does not recognize some local dependencies (they are modules on the code itself, not external dependencies).

example:

import (
	&quot;&lt;private-repo-url&gt;/src/cmd/http-api/bootstrap&quot; // this a local module that&#39;s part of the server
	&quot;go.uber.org/fx&quot;
)

func main() {
	fx.New(bootstrap.Module).Run()
}

Here's the error:

 =&gt; ERROR [7/7] RUN go build -a -o ./server                                                                                                                                                                        0.3s
------
 &gt; [7/7] RUN go build -a -o ./server:
#10 0.295 server.go:4:2: no required module provides package &lt;private-repo-url&gt;/src/cmd/http-api/bootstrap; to add it:
#10 0.295       go get &lt;private-repo-url&gt;/src/cmd/http-api/bootstrap
------
executor failed running [/bin/sh -c go build -a -o ./server]: exit code: 1

Please note that this private-repo-url corresponds to this application's repository (it's not an external dependency).

Here's the Dockerfile

FROM golang:1.17

WORKDIR /balrog

# Copy dependency definitions and download them
ADD go.mod .
ADD go.sum .
RUN go mod download

# Build the binary
ADD ./src .
ENV CGO_ENABLED=0
ENV GOOS=linux
ENV GOARCH=amd64
RUN go build -a -o ./server

#Run the server
CMD [&quot;/server&quot;]

And the mod.go file:

module &lt;private-repo-url&gt;

go 1.16

require (
	github.com/gin-gonic/gin v1.7.7
	github.com/google/uuid v1.3.0
	github.com/kelseyhightower/envconfig v1.4.0
	github.com/sirupsen/logrus v1.8.1
	go.uber.org/fx v1.15.0
)

I've read about GO111MODULE saying it should be on, and I also read that it's enabled by default from 1.17 (here).

Also according to the official docker image (in dockerhub) the right way is using go get and go install after copying all the files. This approach lead me to a slightly different problem which is that the docker can not access the repository (because it's private) and adding credentials to the docker is something I'd like to avoid.

I tried to play arround with the environment variable GOVCS setting it's value like:

ENV GOVCS=github.com:git,gitlab.com:off

But it still did fail with the same error.

Finally I tried with the replace, I figured that if I removed the <private-repo-url> from the local dependencies it would work, so I executed (inside the Dockerfile) this:

RUN go mod edit -replace &lt;private-repo-url&gt;=./

Again it did fail with:

 =&gt; ERROR [builder 10/10] RUN go build -a -o ./server                                                                                                                                                              0.3s
------                                                                                                                                                                                                                  
 &gt; [builder 10/10] RUN go build -a -o ./server:                                                                                                                                                                         
#17 0.299 server.go:4:2: module &lt;private-repo-url&gt;/src provides package &lt;private-repo-url&gt;/src/cmd/http-api/bootstrap and is replaced but not required; to add it:
#17 0.299       go get &lt;private-repo-url&gt;/src
#17 0.299 server.go:5:2: no required module provides package go.uber.org/fx; to add it:
#17 0.299       go get go.uber.org/fx

Is there any way to prevent go builder/package installer to look for these files externally? As both go mod and go get + go install try to access this private repository and fail as they do not have access. But they should not try to access it on the first place as it's the application's repository... Or is that I'm doing something wrong (clearly or I wouldn't be here), missing something?

答案1

得分: 3

ADD ./src . - 这将把src文件夹的内容复制到当前文件夹,并去掉src部分。

应该改为COPY . ./

另外,请注意不建议在源代码树中使用src子文件夹 - 包含go.mod的文件夹已经是源代码树了。

英文:

ADD ./src . - that copies the contents of src to the current folder, stripping away the src part.

It should just be COPY . ./

Also note that it's not recommended to have a src subfolder in your source tree - the folder that contains go.mod is already the source tree.

huangapple
  • 本文由 发表于 2021年12月3日 05:50:02
  • 转载请务必保留本文链接:https://go.coder-hub.com/70206905.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定