docker - 为多个go.mod项目编写dockerfile

标签 docker go

有一个用 Go 编写的库。其文件夹结构为:

lib/
    golang/
        go.mod
        lib.go
        example/
            golang/
                proto/
                    protofile
                go.mod
                main.go
                Dockerfile

example是展示如何使用这个lib的文件夹,因此它有一个可以构建和运行的main.go。为了使用该库,example/golang/go.mod 是:

module golang

go 1.15

require (
    lib/golang v0.0.0
    other stuff...
)

replace lib/golang => ../../golang
    

现在我想将可运行的示例打包成docker镜像,Dockerfile为:

FROM golang:1.15

WORKDIR /go/src/app
COPY . .

RUN go env -w GO111MODULE=auto
RUN go env -w GOPROXY=https://goproxy.io,direct

RUN go get -d -v ./...
RUN go install -v ./...

CMD ["app"]

然后我 cd 进入 example/golang run docker build -t example . ,错误日志为

open /go/golang/go.mod: no such file or directory

似乎无法访问 lib/go.mod 文件,然后我 cd 进入 lib 文件夹并运行 docker build -t server -f examples/golang/Dockerfile . ,但这会影响 main.go 的导入:

import "golang/proto"

错误日志是:

golang/proto: unrecognized import path "golang/proto"

我应该如何修复这个问题来制作 docker 镜像?

============================================

在我花了一些时间阅读docker doc之后,这里是关于这个问题的总结:

docker build 命令遵循 PATH 参数,即点 .在最后。控制构建的内容,它决定了 docker build 可以访问哪些文件。所以第一个错误的原因是pwd是lib/example/golang,docker build命令路径是. ,那么 docker build 无法访问 lib/example/golang 的父文件,并且它们在 main.go 中需要作为 lib。 命令应该是:docker build -t example ../../但是,docker build 仅在内容路径的根目录中查找 Dockerfile,因此使用 -f 告诉它 Dockerfile 所在的位置:docker build -t example -f ./Dockerfile ../../

如果 pwd 为 lib/,则命令为 docker build -t server -f examples/golang/Dockerfile .

简短:

  1. 如果 dockerfile 不位于项目根路径,请使用 docker build 命令的 -f 和 PATH 为其提供足够的文件访问权限。如果使用 go 模块,请确保 PATH 包含 go.mod 文件
  2. 如果 main.go 位于子文件夹中,请确保 dockerfile 中的 WORKDIR 与 COPY 全部需要后的子文件夹相同,否则 go build 或 go install 无法编译

最佳答案

您的Dockerfile 嵌套太多。由于您的 go build 依赖于相对路径(父目录中的路径),因此 docker build 不会看到任何父目录文件。

Dockerfile 移至顶部,例如

Dockerile
lib/

并更新以构建嵌套构建目录:

FROM golang:1.15

WORKDIR /go/src/app

# just need to copy lib tree
COPY lib .  

# working from here now
WORKDIR /go/src/app/lib/golang/example/golang 

RUN go env -w GO111MODULE=auto    
RUN go env -w GOPROXY=https://goproxy.io,direct

RUN go get -d -v ./...
RUN go install -v ./...

CMD ["app"]

关于docker - 为多个go.mod项目编写dockerfile,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64661817/

相关文章:

php - Dockerized Laravel 应用程序,总是 404 Assets

docker - Docker中的Debian httpredir镜像系统不可靠/不可用?

serialization - Golang 序列化和反序列化

go - channel是否发送抢占点用于goroutine调度?

git - 为什么我要从 repo URL 构建 docker?

docker - 将容器DNS暴露给另一个容器?

docker - 查看临时 docker 容器的标准输出和日志

go - 对特定主机使用 TLS/SSL 客户端身份验证

http - 戈朗 : Simultaneous function Calls for http post request

git - 如何用 Go 解压一个 git pack 文件?