Home  >  Article  >  Backend Development  >  Unable to execute go binary using docker multi-stage build

Unable to execute go binary using docker multi-stage build

王林
王林forward
2024-02-05 23:45:121071browse

无法使用 docker 多阶段构建执行 go 二进制文件

Question content

I try to build a go application as follows, my main.go file is located at cmd/app/main.go.

However, when I try to run docker build --no-cache . and docker runs a3f94dbaba3a4609eaf634c1155b4c45. It gives me exec ./bin/app: No such file or directory

I have tested running go build -o ./bin/app ./cmd/app and ./bin/app can run correctly.

This is my dockerfile

# build phase
from golang:1.20 as builder

workdir /app

copy go.mod go.sum ./
run go mod download && go mod verify

copy . .
run go build -o ./bin/app ./cmd/app

# production phase
from alpine:3.14

workdir /app

copy --from=builder /app/bin/app ./bin/app

entrypoint [ "./bin/app" ]

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

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

Thanks.

how to solve this problem?


Correct answer


First of all, there are some problems with the path, causing No such file or directory error.
I wrote a minimal dockerfile example and renamed the app binary, which caused confusion since it was in the app directory in the example. I hope it makes more sense now.

Second, after fixing the path inaccuracy in dockerfile, you will encounter a more subtle problem when trying to run the go binary: Not found because golang The builder image is using debian glibc 2.31-13 deb11u5 2.31 and the runner image is using musl libc (x86_64) Version 1.2.2.

The easiest fix is ​​to set cgo_enabled=0 at build time. If you do want to compile with cgo, please find a builder and runner image that is compatible in this regard.
Several alternatives and workarounds are provided for similar problems here.

Third, you also mentioned the .env file in your comments, so I also added a simple read display in mvp for using docker run --env. .. Injected environment variables.

.
├── cmd
│   └── main.go
├── dockerfile
├── go.mod
└── go.sum

dockerfile:

# build phase
from golang:1.20 as builder
# next line is just for debug
run ldd --version
workdir /build
copy go.mod go.sum ./
run go mod download && go mod verify
copy . .
workdir /build/cmd
run cgo_enabled=0 goos=linux goarch=amd64 go build -o go-binary

# production phase
from alpine:3.14
# next line is just for debug
run ldd; exit 0
workdir /app
copy --from=builder /build/cmd/go-binary .
entrypoint [ "/app/go-binary"]

main.go:

package main

import (
    "os"
    "time"

    "github.com/rs/zerolog/log"
)

func main() {
    yourvar := os.getenv("your_var")
    for {
        time.sleep(time.second)
        log.info().msg(yourvar)
    }
}

Build and run:

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

The above is the detailed content of Unable to execute go binary using docker multi-stage build. For more information, please follow other related articles on the PHP Chinese website!

Statement:
This article is reproduced at:stackoverflow.com. If there is any infringement, please contact admin@php.cn delete