无法使用Docker多阶段构建执行Go二进制文件。

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

Can't execute go binary with docker multi stage build

问题

我尝试按照以下方式构建Go应用程序,我的main.go文件位于cmd/app/main.go。

然而,当我尝试运行docker build --no-cache .docker run <container_id>时,它给出了exec ./bin/app: no such file or directory的错误。

我已经测试过运行go build -o ./bin/app ./cmd/app./bin/app是可以正常运行的。

这是我的Dockerfile:

  1. # Build phase
  2. FROM golang:1.20 AS builder
  3. WORKDIR /app
  4. COPY go.mod go.sum ./
  5. RUN go mod download && go mod verify
  6. COPY . .
  7. RUN go build -o ./bin/app ./cmd/app
  8. # Production phase
  9. FROM alpine:3.14
  10. WORKDIR /app
  11. COPY --from=builder /app/bin/app ./bin/app
  12. ENTRYPOINT ["./bin/app"]

我尝试进入容器docker run -it -t fyno/server/multi /bin/sh

  1. /app # cd bin
  2. /app/bin # ls -la
  3. total 11636
  4. drwxr-xr-x 2 root root 4096 Apr 12 05:04 .
  5. drwxr-xr-x 1 root root 4096 Apr 12 05:04 ..
  6. -rwxr-xr-x 1 root root 11904381 Apr 12 05:04 app
  7. /app/bin # ./app
  8. /bin/sh: ./app: not found
  9. /app/bin #

谢谢。

如何解决这个问题?

英文:

I try to build the go app as follow, my main.go file is at cmd/app/main.go.

However, when I try running docker build --no-cache . and docker run &lt;container_id&gt;.
It gives me exec ./bin/app: no such file or directory

I've already test that running go build -o ./bin/app ./cmd/app and ./bin/app is able to run correctly.

Here is my Dockerfile

  1. # Build phase
  2. FROM golang:1.20 AS builder
  3. WORKDIR /app
  4. COPY go.mod go.sum ./
  5. RUN go mod download &amp;&amp; go mod verify
  6. COPY . .
  7. RUN go build -o ./bin/app ./cmd/app
  8. # Production phase
  9. FROM alpine:3.14
  10. WORKDIR /app
  11. COPY --from=builder /app/bin/app ./bin/app
  12. ENTRYPOINT [ &quot;./bin/app&quot; ]

I tried to access into the container docker run -it -t fyno/server/multi /bin/sh

  1. /app # cd bin
  2. /app/bin # ls -la
  3. total 11636
  4. drwxr-xr-x 2 root root 4096 Apr 12 05:04 .
  5. drwxr-xr-x 1 root root 4096 Apr 12 05:04 ..
  6. -rwxr-xr-x 1 root root 11904381 Apr 12 05:04 app
  7. /app/bin # ./app
  8. /bin/sh: ./app: not found
  9. /app/bin #

Thanks.

how to fix the problem?

答案1

得分: 1

首先,路径存在一些问题,导致出现了“没有该文件或目录”的错误。我写了一个简单的Dockerfile示例,并将导致混淆的app二进制文件重命名,因为在你的示例中它位于一个名为app的目录中。希望现在更清楚了。

其次,在修复Dockerfile中路径不准确的问题后,你遇到了一个更微妙的问题,即尝试运行Go二进制文件时出现“找不到”,因为golang构建器镜像使用的是“Debian GLIBC 2.31-13+deb11u5 2.31”,而运行镜像使用的是“musl libc (x86_64) Version 1.2.2”。

最简单的解决方法是在构建时设置CGO_ENABLED=0。如果你真的想使用cgo进行编译,请找到在这方面兼容的构建器和运行镜像。有关类似问题的几种替代方案和解决方法,请参考这里

第三,你在评论中提到了.env文件,所以我在MVP中还包含了一个简单的读取和显示使用docker run --env ...注入的环境变量。

以下是示例代码:

  1. .
  2. ├── cmd
  3. └── main.go
  4. ├── Dockerfile
  5. ├── go.mod
  6. └── go.sum

Dockerfile:

  1. # Build phase
  2. FROM golang:1.20 AS builder
  3. # Next line is just for debug
  4. RUN ldd --version
  5. WORKDIR /build
  6. COPY go.mod go.sum ./
  7. RUN go mod download && go mod verify
  8. COPY . .
  9. WORKDIR /build/cmd
  10. RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o go-binary
  11. # Production phase
  12. FROM alpine:3.14
  13. # Next line is just for debug
  14. RUN ldd; exit 0
  15. WORKDIR /app
  16. COPY --from=builder /build/cmd/go-binary .
  17. ENTRYPOINT ["/app/go-binary"]

main.go:

  1. package main
  2. import (
  3. "os"
  4. "time"
  5. "github.com/rs/zerolog/log"
  6. )
  7. func main() {
  8. yourVar := os.Getenv("YOUR_VAR")
  9. for {
  10. time.Sleep(time.Second)
  11. log.Info().Msg(yourVar)
  12. }
  13. }

构建和运行命令:

  1. docker build --no-cache -t stack-overflow-go-docker:v1.0 .
  2. docker run --env YOUR_VAR=your-value stack-overflow-go-docker:v1.0

输出结果:

  1. {"level":"info","time":"2023-04-14T21:12:37Z","message":"your-value"}
  2. {"level":"info","time":"2023-04-14T21:12:38Z","message":"your-value"}
英文:

First, there are some problems with the paths, causing your no such file or directory error.
I wrote a minimal Dockerfile example and renamed the app binary which was causing confusion because it was located in an app directory in your example. I hope it makes more sense now.

Second, after fixing the paths inaccuracies in the Dockerfile, you run into a more subtle problem, when trying to run the go binary: not found, because the the golang builder image is using Debian GLIBC 2.31-13+deb11u5 2.31 while the runner image is using musl libc (x86_64)
Version 1.2.2
.

The easiest fix is to set CGO_ENABLED=0 when building. If you really want to use cgo to compile, find a builder and a runner images that are compatible in this regard.
Several alternatives and workarounds are provided for a similar question here.

Third, you also mentioned about the .env file in a comment so I also included in the MVP a simple read-display for an environment variable injected with docker run --env ....

  1. .
  2. ├── cmd
  3. └── main.go
  4. ├── Dockerfile
  5. ├── go.mod
  6. └── go.sum

Dockerfile:

  1. # Build phase
  2. FROM golang:1.20 AS builder
  3. # Next line is just for debug
  4. RUN ldd --version
  5. WORKDIR /build
  6. COPY go.mod go.sum ./
  7. RUN go mod download &amp;&amp; go mod verify
  8. COPY . .
  9. WORKDIR /build/cmd
  10. RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o go-binary
  11. # Production phase
  12. FROM alpine:3.14
  13. # Next line is just for debug
  14. RUN ldd; exit 0
  15. WORKDIR /app
  16. COPY --from=builder /build/cmd/go-binary .
  17. ENTRYPOINT [ &quot;/app/go-binary&quot;]

main.go:

  1. package main
  2. import (
  3. &quot;os&quot;
  4. &quot;time&quot;
  5. &quot;github.com/rs/zerolog/log&quot;
  6. )
  7. func main() {
  8. yourVar := os.Getenv(&quot;YOUR_VAR&quot;)
  9. for {
  10. time.Sleep(time.Second)
  11. log.Info().Msg(yourVar)
  12. }
  13. }

Build and run:

  1. docker build --no-cache -t stack-overflow-go-docker:v1.0 .
  2. docker run --env YOUR_VAR=your-value stack-overflow-go-docker:v1.0
  1. {&quot;level&quot;:&quot;info&quot;,&quot;time&quot;:&quot;2023-04-14T21:12:37Z&quot;,&quot;message&quot;:&quot;your-value&quot;}
  2. {&quot;level&quot;:&quot;info&quot;,&quot;time&quot;:&quot;2023-04-14T21:12:38Z&quot;,&quot;message&quot;:&quot;your-value&quot;}

huangapple
  • 本文由 发表于 2023年4月12日 12:47:11
  • 转载请务必保留本文链接:https://go.coder-hub.com/75991985.html
匿名

发表评论

匿名网友

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

确定