首頁  >  文章  >  後端開發  >  無法使用 docker 多階段建置執行 go 二進位文件

無法使用 docker 多階段建置執行 go 二進位文件

王林
王林轉載
2024-02-05 23:45:121071瀏覽

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

問題內容

我嘗試按如下方式建立 go 應用程序,我的 main.go 檔案位於 cmd/app/main.go。

但是,當我嘗試執行 docker build --no-cache .docker 運行 a3f94dbaba3a4609eaf634c1155b4c45 時。 它給了我 exec ./bin/app: 沒有這樣的檔案或目錄

我已經測試過運行 go build -o ./bin/app ./cmd/app./bin/app 能夠正確運行。

這是我的 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" ]

我嘗試存取容器 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 #

謝謝。

如何解決這個問題?


正確答案


首先,路徑存在一些問題,導致沒有這樣的檔案或目錄錯誤。
我編寫了一個最小的 dockerfile 範例,並重命名了 app 二進位文件,這導致了混亂,因為它位於範例中的 app 目錄中。我希望它現在更有意義。

其次,在修復dockerfile 中的路徑不準確之後,當嘗試執行go 二進位時,您會遇到一個更微妙的問題:找不到,因為golang建構器映像正在使用debian glibc 2.31-13 deb11u5 2.31,而執行程式映像則使用musl libc (x86_64) 版本 1.2.2

最簡單的修復方法是在建置時設定 cgo_enabled=0 。如果你確實想使用 cgo 進行編譯,請找到在這方面相容的 builder 和 runner 映像。
針對類似問題提供了幾個替代方案和解決方法這裡

第三,您還在評論中提到了.env 文件,因此我還在mvp 中添加了一個簡單的讀取顯示,用於使用docker run --env . .. 注入的環境變數。

.
├── 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)
    }
}

建置並運行:

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"}

以上是無法使用 docker 多階段建置執行 go 二進位文件的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:stackoverflow.com。如有侵權,請聯絡admin@php.cn刪除