Maison >développement back-end >Golang >Erreur d'exécution de Docker : exec /app/backend/server : aucun fichier ou répertoire de ce type

Erreur d'exécution de Docker : exec /app/backend/server : aucun fichier ou répertoire de ce type

WBOY
WBOYavant
2024-02-08 21:21:181186parcourir

Docker 运行错误:exec /app/backend/server:没有这样的文件或目录

Lors de l'utilisation de Docker, vous rencontrez parfois des erreurs d'exécution, telles que le message d'erreur "exec /app/backend/server : aucun fichier ou répertoire de ce type". Cette erreur peut laisser les gens perplexes quant à la façon de la corriger. En réponse à ce problème, l'éditeur PHP Yuzai a proposé des solutions pour tout le monde, dans l'espoir d'aider tout le monde. Voyons ensuite comment résoudre ce problème.

Contenu de la question

J'ai du mal à essayer d'exécuter un conteneur Docker. J'ai construit une image à partir d'un Dockerfile :

docker build -t server -f ./backend/Dockerfile .

Exécutez-le :

docker run -it -p 8081:8081 server

Une erreur s'est produite :

exec /app/backend/server: no such file or directory

Lorsque je vérifie depuis Docker Desktop, je vois que le fichier existe à l'intérieur du conteneur et a été créé à l'emplacement où il devrait se trouver.

J'ai également essayé de changer le deuxième étage FROM golang:1.21-alpine mais j'ai toujours la même erreur.

Avec de gcr.io/distroless/base-debian11 j'obtiens :

/app/backend/server: /lib/aarch64-linux-gnu/libc.so.6: version `GLIBC_2.33' not found (required by /app/backend/server)
/app/backend/server: /lib/aarch64-linux-gnu/libc.so.6: version `GLIBC_2.32' not found (required by /app/backend/server)
/app/backend/server: /lib/aarch64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found (required by /app/backend/server)

J'ai regardé ici, ici et j'ai essayé beaucoup de choses. Je suis relativement nouveau sur Docker et je ne sais pas comment résoudre ce problème. Quelqu'un peut-il m'aider à comprendre ce qui pourrait causer cette erreur et comment y remédier ? Merci d'avance!

Voici mon Dockerfile :

# Stage 1: Building the application
FROM golang:1.21 AS builder

WORKDIR /app

COPY go.mod go.sum ./
RUN go mod download

COPY . ./

RUN apt-get update && apt-get install -y sqlite3 libsqlite3-dev
RUN CGO_ENABLED=1 GOOS=linux go build -a -installsuffix cgo -o /app/backend/server ./backend/backend.go

# Stage 2: Production stage using Alpine
FROM alpine:latest

RUN apk --no-cache add ca-certificates sqlite 

COPY ./backend/configs/config /app/configs/config
COPY ./database/sqlite/schema.sql /app/database/sqlite/schema.sql

COPY ./tls/server.crt /tls/server.crt
COPY ./tls/server.key /tls/server.key

COPY --from=builder /app/backend/server /app/backend/server

EXPOSE 8081

ENTRYPOINT ["/app/backend/server"]

Solution de contournement

J'ai reproduit votre problème avec une dockerfile et une application simplifiées (veuillez essayer de fournir un exemple minimal et reproductible - J'ai dû deviner quelle bibliothèque SQLite vous utilisiez) :

backend.go

package main

import (
    "database/sql"
    "log"
    "os"

    _ "github.com/mattn/go-sqlite3"
)

func main() {
    os.Remove("./foo.db")

    db, err := sql.Open("sqlite3", "./foo.db")
    if err != nil {
        log.Fatal(err)
    }
    defer db.Close()

    sqlStmt := `
    create table foo (id integer not null primary key, name text);
    delete from foo;
    `
    _, err = db.Exec(sqlStmt)
    if err != nil {
        log.Printf("%q: %s\n", err, sqlStmt)
        return
    }
}

dockerfile :

# Stage 1: Building the application
FROM golang:1.21 AS builder
WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download
COPY . ./
RUN apt-get update && apt-get install -y sqlite3 libsqlite3-dev
RUN CGO_ENABLED=1 GOOS=linux go build -a -installsuffix cgo -o /app/server

# Stage 2: Production stage using Alpine
FROM alpine:latest
RUN apk --no-cache add ca-certificates sqlite
COPY --from=builder /app/server /app/server
EXPOSE 8081
ENTRYPOINT ["/app/server"]

En démarrant un shell dans le conteneur (docker run -it --entrypoint /bin/sh server) on voit que l'exécutable est là, les permissions sont bonnes, mais il ne s'exécute pas :

/ # ls -al /app/server
-rwxr-xr-x    1 root     root       6816280 Sep 22 02:29 /app/server
/ # /app/server
/bin/sh: /app/server: not found
/ # ldd /app/server
        /lib64/ld-linux-x86-64.so.2 (0x7ff8cb4ba000)
        libc.so.6 => /lib64/ld-linux-x86-64.so.2 (0x7ff8cb4ba000)
Error relocating /app/server: fcntl64: symbol not found

Il est facile de voir l'erreur « introuvable » et de penser que cela doit être dû au fait que le fichier ne se trouve pas là où vous l'attendez ou qu'il a des autorisations incorrectes. Cependant, la même erreur s'affiche lorsqu'il manque quelque chose dont dépend l'exécutable. lddldd 显示问题 - 可执行文件依赖于 fcntl64;该库由 glibc 提供,但不是 musl (如 Alpine 中使用的 - glibc musl Problème d'affichage - l'exécutable dépend de fcntl64<a href="https://www.php.cn/link/75800f73fa80f935216b8cfbedf77bfa" rel="noreferrer">;Cette bibliothèque est fournie par <code>glibc mais pas par musl (tel qu'utilisé dans Alpine - glibc et musl Incompatibilités entre code> ne sont pas rares

).

La solution la plus simple consiste à compiler l'application en utilisant le même système d'exploitation que celui sur lequel l'application s'exécute :

# Stage 1: Building the application
FROM golang:1.21-alpine AS builder
WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download
COPY . ./
RUN apk --no-cache add gcc g++ sqlite
RUN CGO_ENABLED=1 GOOS=linux go build -a -installsuffix cgo -o /app/server

# Stage 2: Production stage using Alpine
FROM alpine:latest
RUN apk --no-cache add ca-certificates sqlite
COPY --from=builder /app/server /app/server
EXPOSE 8081
ENTRYPOINT ["/app/server"]

Ensuite, exécutez ceci (aucune sortie de mon exécutable, mais j'ai confirmé que la base de données a été créée) :

/ # ls -al /app/server
-rwxr-xr-x    1 root     root       6838120 Sep 22 02:39 /app/server
/ # /app/server
/ # ldd /app/server
        /lib/ld-musl-x86_64.so.1 (0x7fabcb701000)
        libc.musl-x86_64.so.1 => /lib/ld-musl-x86_64.so.1 (0x7fabcb701000)
/ # ls -al ./foo.db 
-rw-r--r--    1 root     root          8192 Sep 22 02:40 ./foo.db
Une autre option consiste à utiliser la bibliothèque pure go

(aucun CGO requis). 🎜

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