Maison  >  Article  >  développement back-end  >  Impossible d'exécuter le binaire go à l'aide de la construction en plusieurs étapes de Docker

Impossible d'exécuter le binaire go à l'aide de la construction en plusieurs étapes de Docker

王林
王林avant
2024-02-05 23:45:121074parcourir

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

Contenu de la question

J'essaie de créer une application go comme suit, mon fichier main.go se trouve dans cmd/app/main.go.

Mais quand j'essaie de courir docker build --no-cache .docker 运行 a3f94dbaba3a4609eaf634c1155b4c45 . Ça m'a donné exec ./bin/app: 没有这样的文件或目录

J'ai testé le fonctionnement go build -o ./bin/app ./cmd/app./bin/app et cela fonctionne correctement.

Voici mon fichier docker

# 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" ]

J'essaie d'accéder au conteneur 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 #

Merci.

Comment résoudre ce problème ?


Bonne réponse


Tout d'abord, il y a un problème avec le chemin, provoquant l'erreur Aucun fichier ou répertoire de ce type.
J'ai écrit un répertoire minimal dockerfile 示例,并重命名了 app 二进制文件,这导致了混乱,因为它位于示例中的 app. J'espère que cela a plus de sens maintenant.

Deuxièmement, après avoir corrigé l'inexactitude du chemin dans dockerfile, vous rencontrerez un problème plus subtil en essayant d'exécuter le binaire go : introuvable, car l'image du constructeur golang utilise debian glibc 2.31-13+ deb11u5 2.31, tandis que l'image du coureur utilise musl libc (x86_64) Version 1.2.2.

La solution la plus simple consiste à définir cgo_enabled=0 。如果你确实想使用 cgo au moment de la compilation pour la compilation, veuillez trouver des images de générateur et d'exécution compatibles à cet égard.
Plusieurs alternatives et solutions de contournement sont proposées pour des problèmes similaires ici.

Troisièmement, vous avez également mentionné .env 文件,因此我还在 mvp 中添加了一个简单的读取显示,用于使用 docker run --env ... les variables d'environnement injectées dans vos commentaires.

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

Construire et exécuter :

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

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer