Dockerfile 中安装 Go 的软件包。

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

Dockerfile packages go

问题

我有一个用Go和Gin编写的应用程序,该文件分为以下几个部分:

main.go
controller
controllers.go
database
database.go
middleware
middleware.go
models
models.go
routes
routes.go
go.mod
go.sum
Dockerfile

在每个文件夹中,我都有一个调用另一个包的包,例如:

package controller

import (
"log"
"net/http"
"os"

gomail "gopkg.in/mail.v2"

"github.com/dgrijalva/jwt-go"
"github.com/gin-gonic/gin"
models "github.com/guilherm5/login-user/models"

)

package routes

import (
"github.com/gin-gonic/gin"
controller "github.com/guilherm5/login-user/controller"
middleware "github.com/guilherm5/login-user/middleware"
)

我的go.mod文件如下:

module github.com/guilherm5/login-user

go 1.20

require (
github.com/dgrijalva/jwt-go v3.2.0+incompatible
github.com/gin-gonic/gin v1.9.0
github.com/golang-jwt/jwt v3.2.2+incompatible
github.com/joho/godotenv v1.5.1
github.com/lib/pq v1.10.9
golang.org/x/crypto v0.9.0
gopkg.in/mail.v2 v2.3.1
)

require (
github.com/bytedance/sonic v1.8.0 // indirect
github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 // indirect
github.com/gin-contrib/sse v0.1.0 // indirect
github.com/go-playground/locales v0.14.1 // indirect
github.com/go-playground/universal-translator v0.18.1 // indirect
github.com/go-playground/validator/v10 v10.11.2 // indirect
github.com/goccy/go-json v0.10.0 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/klauspost/cpuid/v2 v2.0.9 // indirect
github.com/leodido/go-urn v1.2.1 // indirect
github.com/mattn/go-isatty v0.0.17 // indirect
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/pelletier/go-toml/v2 v2.0.6 // indirect
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
github.com/ugorji/go/codec v1.2.9 // indirect
golang.org/x/arch v0.0.0-20210923205945-b76863e36670 // indirect
golang.org/x/net v0.10.0 // indirect
golang.org/x/sys v0.8.0 // indirect
golang.org/x/text v0.9.0 // indirect
google.golang.org/protobuf v1.28.1 // indirect
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)

然后按照我的应用程序流程进行操作。

我想制作这个应用程序的Docker镜像(出于学习目的,我想学习Docker的基础知识,所以我制作了这个用于测试的API)。

Dockerfile如下:

FROM golang:1.20 as build

WORKDIR /mail

COPY go.sum ./
COPY go.mod ./
COPY main.go ./

RUN go mod download
RUN go build -o /appMail

FROM gcr.io/distroless/base-debian10

WORKDIR /

COPY --from=build /mail /mail

EXPOSE 4000/

USER nonroot:nonroot

ENTRYPOINT ["/appMail"]

在尝试构建镜像时,我遇到了错误:

=> ERROR [build 7/7] RUN go build -o /appMail 0.7s

[build 7/7] RUN go build -o /appMail:
#13 0.680 main.go:5:2: no required module provides package github.com/guilherm5/login-user/routes; to add it:
#13 0.680 go get github.com/guilherm5/login-user/routes


executor failed running [/bin/sh -c go build -o /appMail]: exit code: 1

有人知道为什么吗?我真的不知道该怎么解决,如何将我的包导入到Docker镜像中?

-- 编辑

根据建议,我更新了Dockerfile:

FROM golang:1.20 as build

WORKDIR /mail

COPY go.sum ./
COPY go.mod ./
COPY main.go ./

RUN go mod tidy
RUN go mod download
RUN go build -o /appMail

FROM gcr.io/distroless/base-debian10

WORKDIR /

COPY --from=build /mail /mail

EXPOSE 4000/

USER nonroot:nonroot

ENTRYPOINT ["/appMail"]

错误信息如下:

github.com/guilherm5/login-user imports
#12 9.121 github.com/guilherm5/login-user/routes: cannot find module providing package github.com/guilherm5/login-user/routes: module github.com/guilherm5/login-user/routes: git ls-remote -q origin in /go/pkg/mod/cache/vcs/a7be81f5c5695c6941aa1b7f5a49aa0800b2d648c4d72609eb5feae6f51cf505: exit status 128:
#12 9.121 fatal: could not read Username for 'https://github.com': terminal prompts disabled
#12 9.121 Confirm the import path was entered correctly.
#12 9.121 If this is a private repository, see https://golang.org/doc/faq#git_https for additional information.

executor failed running [/bin/sh -c go mod tidy]: exit code: 1

英文:

I have an app written in go and gin, this file is divided as follows:

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-html -->

main.go 
	controller 
		controllers.go 
	database 	
		database.go 
	middleware 
		middleware.go 
	models 
		models.go 
	routes 
		routes.go 
go.mod 
go.sum 
Dockerfile

<!-- end snippet -->

and in each of these folders I have a package that calls another package, for example:

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-html -->

package controller

import (
	&quot;log&quot;
	&quot;net/http&quot;
	&quot;os&quot;

	gomail &quot;gopkg.in/mail.v2&quot;

	&quot;github.com/dgrijalva/jwt-go&quot;
	&quot;github.com/gin-gonic/gin&quot;
	models &quot;github.com/guilherm5/login-user/models&quot;
)

<!-- end snippet -->

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-html -->

package routes

import (
	&quot;github.com/gin-gonic/gin&quot;
	controller &quot;github.com/guilherm5/login-user/controller&quot;
	middleware &quot;github.com/guilherm5/login-user/middleware&quot;
)

<!-- end snippet -->

my go.mod is like this:

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-html -->

module github.com/guilherm5/login-user



go 1.20

require (
	github.com/dgrijalva/jwt-go v3.2.0+incompatible
	github.com/gin-gonic/gin v1.9.0
	github.com/golang-jwt/jwt v3.2.2+incompatible
	github.com/joho/godotenv v1.5.1
	github.com/lib/pq v1.10.9
	golang.org/x/crypto v0.9.0
	gopkg.in/mail.v2 v2.3.1
)

require (
	github.com/bytedance/sonic v1.8.0 // indirect
	github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 // indirect
	github.com/gin-contrib/sse v0.1.0 // indirect
	github.com/go-playground/locales v0.14.1 // indirect
	github.com/go-playground/universal-translator v0.18.1 // indirect
	github.com/go-playground/validator/v10 v10.11.2 // indirect
	github.com/goccy/go-json v0.10.0 // indirect
	github.com/json-iterator/go v1.1.12 // indirect
	github.com/klauspost/cpuid/v2 v2.0.9 // indirect
	github.com/leodido/go-urn v1.2.1 // indirect
	github.com/mattn/go-isatty v0.0.17 // indirect
	github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 // indirect
	github.com/modern-go/reflect2 v1.0.2 // indirect
	github.com/pelletier/go-toml/v2 v2.0.6 // indirect
	github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
	github.com/ugorji/go/codec v1.2.9 // indirect
	golang.org/x/arch v0.0.0-20210923205945-b76863e36670 // indirect
	golang.org/x/net v0.10.0 // indirect
	golang.org/x/sys v0.8.0 // indirect
	golang.org/x/text v0.9.0 // indirect
	google.golang.org/protobuf v1.28.1 // indirect
	gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect
	gopkg.in/yaml.v3 v3.0.1 // indirect
)

<!-- end snippet -->

and so it goes following the flow of my application..

I want to make a docker image of this application (for learning purposes, I want to learn the basics of docker so I made this api for testing)

docker image:

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-html -->

FROM golang:1.20 as build 

WORKDIR /mail 

COPY go.sum ./
COPY go.mod ./
COPY main.go ./


RUN go mod download
RUN go build -o /appMail

FROM gcr.io/distroless/base-debian10

WORKDIR /

COPY --from=build /mail /mail

EXPOSE 4000/

USER nonroot:nonroot 

ENTRYPOINT [&quot;/appMail&quot;]

<!-- end snippet -->

when trying to build the image I get the error:

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-html -->

=&gt; ERROR [build 7/7] RUN go build -o /appMail             0.7s 
------
 &gt; [build 7/7] RUN go build -o /appMail:
#13 0.680 main.go:5:2: no required module provides package github.com/guilherm5/login-user/routes; to add it:
#13 0.680       go get github.com/guilherm5/login-user/routes   
------
executor failed running [/bin/sh -c go build -o /appMail]: exit code: 1

<!-- end snippet -->

does anyone know why? I really don't know what to do to solve it, how can I import my packages to the docker image?

-- EDIT

I updated my Dockerfile as per suggested to:

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-html -->

FROM golang:1.20 as build 

WORKDIR /mail 

COPY go.sum ./
COPY go.mod ./
COPY main.go ./

RUN go mod tidy
RUN go mod download
RUN go build -o /appMail

FROM gcr.io/distroless/base-debian10

WORKDIR /

COPY --from=build /mail /mail

EXPOSE 4000/

USER nonroot:nonroot 

ENTRYPOINT [&quot;/appMail&quot;]

<!-- end snippet -->

ERROR:

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-html -->

github.com/guilherm5/login-user imports
#12 9.121       github.com/guilherm5/login-user/routes: cannot find module providing package github.com/guilherm5/login-user/routes: module github.com/guilherm5/login-user/routes: git ls-remote -q origin in /go/pkg/mod/cache/vcs/a7be81f5c5695c6941aa1b7f5a49aa0800b2d648c4d72609eb5feae6f51cf505: exit status 128:
#12 9.121       fatal: could not read Username for &#39;https://github.com&#39;: terminal prompts disabled
#12 9.121 Confirm the import path was entered correctly.        
#12 9.121 If this is a private repository, see https://golang.org/doc/faq#git_https for additional information.
------
executor failed running [/bin/sh -c go mod tidy]: exit code: 1 

<!-- end snippet -->

答案1

得分: 3

问题出在 COPY main.go ./ 这里。

Golang 是如何处理依赖包的?

  • 模块缓存:检查包是否存在于 modcache 目录下的 $GOPATH/pkg/mod 中。
  • 项目目录:如果包在 modcache 中找不到,则会检查包是否相对于项目模块根目录存在(例如 github.com/guilherm5/login-user/models - 检查是否存在名为 models 的目录)。
  • 远程仓库:如果包既不在模块缓存中,也不在项目根目录中,则会从远程仓库获取。

在你的情况下,你已经在项目模块根目录中拥有了这些包(目录),但只是将 main.go 复制到了容器系统中。
因此,当运行 go mod tidy 时,它无法在缓存或根目录中找到这些包。然后它会尝试从远程仓库拉取。

我在远程仓库中有代码,为什么它不会拉取?
因为该仓库是私有的。

解决方案

将所有文件和文件夹复制到容器系统中

copy . .

问题将会解决。你已经有了多阶段构建,最终的生产构建中只会包含必要的文件。

参考:

英文:

The issue is happening with COPY main.go ./ this.

How golang will looks the dependencies/packages ?

  • Module Cache : Check the package exists in the modcache $GOPATH/pkg/mod
  • Project Directory : If the package is not found in the modcache, then it will check the packages are exists relative to our projects module root. (github.com/guilherm5/login-user/models - check a directory named as models exists. )
  • Remote : If the packages are not found in the module cache or projects root, then fetch it from remote repository.

In your case you already have the package (directories) within your project module root directory, but only copied the main.go to the container system.
Thus when go mod tidy runs, it couldn't be able to see the packages either in cache or root. Then it is trying to pull it from remote.

I have the code in remote repo, then why it is not pulling ?
Because the repository is private.

Solution

Copy all the files and folder to the container system

copy . . 

and the issue will be resolved. You already have multistage build which will only have the necessary files in the final production build.

See

huangapple
  • 本文由 发表于 2023年6月3日 23:49:30
  • 转载请务必保留本文链接:https://go.coder-hub.com/76396802.html
匿名

发表评论

匿名网友

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

确定