Golang distroless Docker exec failed: No such file or directory when CGO is enabled
Asked Answered
G

1

7

I was trying to get a minimal example go app running inside a docker container. But I kept getting exec /app: no such file or directory when running the container.

I checked and double checked all my paths in the image where I built and copied my application data, even looked inside the container with interactive shell to verify my app was there but nothing worked.

My Dockerfile:

# syntax=docker/dockerfile:1
# BUILD-STAGE
FROM golang:1.17-alpine as build

WORKDIR /go/app

COPY . .

RUN go mod download

RUN go build -o /go/bin/app

# RUN-STAGE
FROM gcr.io/distroless/static-debian11

COPY --from=build /go/bin/app .

EXPOSE 8080

CMD ["./app"]

After several hours of try and error I finally tried to add CGO_ENABLED=0 to my go build command.... and it worked!

My question is now.... why exactly does this happen? There was no error when I built my image with CGO implicitly enabled and I even verified that the binary was copied into my second stage! Why does the runtime say there is no such file when it was built using CGO, but can find it easily when it was built with CGO disabled?

Garboil answered 23/6, 2022 at 7:28 Comment(1)
Thanks! I spent hours trying to figure this out today.Lotty
I
15

The image that you are using does not contain libc 1 which you build your go app against when using CGO_ENABLED=1. As suggested in 1 you can use gcr.io/distroless/base instead of gcr.io/distroless/static. There was no error when building your app because golang:1.17-alpine contains musl libc (something like libc but smaller). Then you tried running the app that required libc in an environment that does not have it anymore. So the no such file error.

google container tools

Iota answered 23/6, 2022 at 9:30 Comment(2)
Thank you for your answer and linking the docs! Would there be any way (a flag maybe?) to let the command tell me which file or directory is missing? The output exec /app: no such file or directory lead me to believe that my binary app could not be found and not a dependency like libc...Garboil
I don't know how to do it when running the compiled go program, but you can check with ldd what dependencies the binary has. Like ldd <path/to/executable>. You will see the difference depending on the value of CGO_ENABLED when compiling.Iota

© 2022 - 2024 — McMap. All rights reserved.