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?
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.