Unable to execute go binary using docker multi-stage build

王林
Release: 2024-02-05 23:45:12
forward
1076 people have browsed it

无法使用 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 <container_id>. 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" ]
Copy after login

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 #
Copy after login

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
Copy after login

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"]
Copy after login

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)
    }
}
Copy after login

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
Copy after login
{"level":"info","time":"2023-04-14T21:12:37Z","message":"your-value"}
{"level":"info","time":"2023-04-14T21:12:38Z","message":"your-value"}
Copy after login

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!

Related labels:
source:stackoverflow.com
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template