I am new to Docker. I want to containerise a small environment so that I can run executables, but I am stuck because I can’t even get an executable to run.
My folder structure looks like this:
example/
|-Dockerfile
|-hello_world
My Dockerfile looks like this:
# Use Alpine Linux as the base image
FROM alpine:latest
# Set the working directory inside the container
WORKDIR /app
# Copy the executable to the container
COPY hello_world /app/
# Set the permissions for the executable
RUN chmod +x /app/hello_world
# Define the command to run your server when the container starts
ENTRYPOINT ["/app/hello_world"]
Then I run:
> sudo docker build -t example .
> sudo docker run --name example_container example
The result of this is this:
exec /app/hello_world: no such file or directory
I have tried as many variations on this as I can think, trying to use CMD, RUN and ENTRYPOINT in the Dockerfile but all have the same result of the image not being able to find the hello_world program in the app folder that exists at the root.
I am really confused because I tried this on my vanilla Ubuntu OS, I put a test folder at the root and then a hello_world in there, and it seemed to work fine that I could run it from wherever with this absolute path.
/app/hello_world is an executable, it’s a compiled bit of Rust code. When I run /app/hello_world in the shell on my Ubuntu machine it works fine.
stable-x86_64-unknown-linux-gnu toolchain/rustc 1.71.0
Could someone please tell me what I am doing wrong?
>Solution :
The reason you see the "no such file or directory" error is because the system is looking for the path embedded in the .interp section of the ELF binary. For a binary compiled under glibc, that looks like:
$ objdump -j .interp -s hello
hello: file format elf64-x86-64
Contents of section .interp:
400318 2f6c6962 36342f6c 642d6c69 6e75782d /lib64/ld-linux-
400328 7838362d 36342e73 6f2e3200 x86-64.so.2.
In your Alpine image, there is no /lib64/ld-linux-x86-64.so.2, which is what leads to the error message.
Using a C binary as an example, if I start with:
#include <stdio.h>
int main() {
printf("Hello world.\n");
return 0;
}
And compile it on my glibc system, then try running it under Alpine, we see:
$ podman run -it --rm -v $PWD:/src -w /src alpine
/src # ./hello
/bin/sh: ./hello: not found
If we make the expected interpreter available, like this:
$ podman run -it --rm -v $PWD:/src -w /src \
-v /lib64/ld-linux-x86-64.so.2:/lib64/ld-linux-x86-64.so.2 alpine
We get a new error:
/src # ./hello
./hello: error while loading shared libraries: libc.so.6: cannot open shared object file: No such file or directory
If we make the necessary shared library available:
$ podman run -it --rm -v $PWD:/src -w /src \
-v /lib64/ld-linux-x86-64.so.2:/lib64/ld-linux-x86-64.so.2 \
-v /lib64/libc.so.6:/lib64/libc.so.6 alpine
Then the command works as expected:
/src # ./hello
Hello world.