将Go API Docker化,如果不设置git项目仓库,则无法正常工作。

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

Dockerizing Go API not working without setting up git project repo

问题

我有一个非常简单的项目-一个具有以下目录结构的Go API:

├── Dockerfile
├── go.mod
├── go.sum
├── main.go
└── user
    ├── repository.go
    └── user.go

我的Dockerfile如下所示:

FROM golang:1.17-alpine
WORKDIR /app
COPY go.mod ./
COPY go.sum ./
RUN go mod download
COPY *.go ./
RUN go build -o /api
CMD ["/api"]

我一直遇到这个错误:

[7/7] RUN go build -o /api:
#11 0.462 main.go:4:2: package api/user is not in GOROOT (/usr/local/go/src/api/user)

阅读了一些资料后,看起来我可能需要设置一个GitHub存储库,让Go从git中拉取代码?我认为这真的很疯狂,因为代码就在Docker镜像中。

如何在不设置像github.com/alex/someproject这样的git存储库的情况下构建/ Dockerize这个Go项目?我问这个问题是因为我不想将其发布到GitHub上-这应该是从本地进行的非常简单的操作。

英文:

I have a very simple project - a Go API with the following directory structure

├── Dockerfile
├── go.mod
├── go.sum
├── main.go
└── user
    ├── repository.go
    └── user.go

My Dockerfile looks like so

FROM golang:1.17-alpine
WORKDIR /app
COPY go.mod ./
COPY go.sum ./
RUN go mod download
COPY *.go ./
RUN go build -o /api
CMD [ "/api" ]

and I keep getting this error:

> [7/7] RUN go build -o /api:
#11 0.462 main.go:4:2: package api/user is not in GOROOT (/usr/local/go/src/api/user)

After reading a bit it looks like I might need to setup a github repository and let go pull the code from git? I think that's honestly crazy since the code is RIGHT THERE in the Docker image.

How can I build/Dockerize this Go project without setting up the git repo like github.com/alex/someproject? Asking because I don't want to publish this onto github - this should be dead simple from local.

答案1

得分: 3

你不需要将Go代码发布到像github.com这样的服务中,只需确保要编译的代码你编译的机器上。你的go build命令失败是因为错误消息中提到的包在机器上找不到。

以下假设Go项目本身是正确的,并且你能够在本地机器上编译它。如果不是这种情况,下面的答案无法帮助你解决问题,你需要在问题中提供更多信息,例如go.mod文件、main.go文件以及user包的内容。

请注意,COPY *.go ./不会递归复制所有的go文件,也就是说它不会复制./user/目录中的文件。

COPY

每个<src>可以包含通配符,并且匹配将使用Go的filepath.Match规则进行。

filepath.Match

模式语法如下:

pattern:
    { term }
term:
    '*'         匹配任意非分隔符字符的序列
    '?'         匹配任意单个非分隔符字符
    '[' [ '^' ] { character-range } ']'
                字符类(必须非空)
    c           匹配字符c(c != '*', '?', '\\', '[')
    '\\' c      匹配字符c

character-range:
    c           匹配字符c(c != '\\', '-', ']')
    '\\' c      匹配字符c
    lo '-' hi   匹配lo <= c <= hi的字符

注意,'*'项匹配任意非分隔符字符的序列,这意味着*.go不会匹配foo/bar.go,因为有分隔符/


在你的Dockerfile中,以下内容应该足够了:

FROM golang:1.17-alpine

WORKDIR /app
COPY . ./
RUN go build -o /api

CMD [ "/api" ]

但是,如果你想选择性地复制文件,可以这样做:

COPY go.mod ./
COPY go.sum ./
COPY user/ ./user/
COPY *.go ./
英文:

You do not need to publish your Go code to a service like github.com just to be able to compile it.

All you need to do is to make sure that the code you want to compile is on the machine on which you are compiling it. Your go build command is failing because the package mentioned in the error message is nowhere on the machine to be found.


<sub>The following assumes that the Go project itself is in order and you are able to compile it on your local machine. If that is not the case and the answer that follows does not help you resolve the problem then you'll need to include more information in your question, like the content of your go.mod file, main.go file, and also the user package.</sub>

Note that COPY *.go ./ will NOT copy all the go files recursively, i.e. it will not copy the files in the ./user/ directory.

COPY:

> Each &lt;src&gt; may contain wildcards and matching will be done using Go’s
> filepath.Match rules.

filepath.Match:
> The pattern syntax is:
>
> none
&gt; pattern:
&gt; { term }
&gt; term:
&gt; &#39;*&#39; matches any sequence of non-Separator characters
&gt; &#39;?&#39; matches any single non-Separator character
&gt; &#39;[&#39; [ &#39;^&#39; ] { character-range } &#39;]&#39;
&gt; character class (must be non-empty)
&gt; c matches character c (c != &#39;*&#39;, &#39;?&#39;, &#39;\\&#39;, &#39;[&#39;)
&gt; &#39;\\&#39; c matches character c
&gt;
&gt; character-range:
&gt; c matches character c (c != &#39;\\&#39;, &#39;-&#39;, &#39;]&#39;)
&gt; &#39;\\&#39; c matches character c
&gt; lo &#39;-&#39; hi matches character c for lo &lt;= c &lt;= hi
&gt;

Notice that the &#39;*&#39; term matches any sequence of non-Separator characters, this means that *.go will not match foo/bar.go because of the separator /.


It should be enough to have the following in your Dockerfile:

FROM golang:1.17-alpine

WORKDIR /app
COPY . ./
RUN go build -o /api

CMD [ &quot;/api&quot; ]

But if you want to be selective about the files you copy, then you can do:

COPY go.mod ./
COPY go.sum ./
COPY user/ ./user/
COPY *.go ./

huangapple
  • 本文由 发表于 2021年11月11日 08:44:05
  • 转载请务必保留本文链接:https://go.coder-hub.com/69921936.html
匿名

发表评论

匿名网友

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

确定