Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Docker Run Error: exec /app/backend/server: no such file or directory

Tags:

linux

docker

go

I'm encountering an issue while trying to run a Docker container. I build a image from Dockerfile:

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

Run it:

docker run -it -p 8081:8081 server

Getting an error:

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

When I go to check from Docker Desktop, then inside the container I see the file exists and is created to that location as it should be.

I also tried changing the second stage FROM golang:1.21-alpine but still getting same error.

With FROM gcr.io/distroless/base-debian11 I am getting:

/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)

I looked here, here and tried many things. I'm relatively new to Docker, and I'm not sure how to troubleshoot this issue. Can someone please help me understand what might be causing this error and how to resolve it? Thanks in advance!

My Dockerfile below:

# 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"]
like image 888
Egon Avatar asked Mar 05 '26 18:03

Egon


1 Answers

I replicated your issue with a simplified dockerfile and app (please try to provide minimal, reproducible, examples - I had to guess which sqlite lib you are using):

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

Starting a shell in the container (docker run -it --entrypoint /bin/sh server) we can see that the executable is there, the permissions are fine, but it does not run:

/ # 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

It's easy to read the error "not found" and think it must be due to the file not being where you expect, or having incorrect permissions. However, the same error is displayed when something the executable depends upon is missing. ldd shows the issue - the executable is relying upon fcntl64; this library is provided by glibc but not musl (as used in Alpine - incompatibilities between glibc and musl are not uncommon).

The simplest solution is to compile the app with the same OS as you will run it on:

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

And run this (my executable has no output but I confirm that the database has been created):

/ # 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

An alternative option is to use a pure go library (removing the need for CGO).

like image 80
Brits Avatar answered Mar 08 '26 09:03

Brits



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!