英文:
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 (
"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"
)
<!-- end snippet -->
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-html -->
package routes
import (
"github.com/gin-gonic/gin"
controller "github.com/guilherm5/login-user/controller"
middleware "github.com/guilherm5/login-user/middleware"
)
<!-- 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 ["/appMail"]
<!-- end snippet -->
when trying to build the image I get the error:
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-html -->
=> 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
<!-- 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 ["/appMail"]
<!-- 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 '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
<!-- 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
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论