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?
2
Answers
Based on the comments I received, here is an answer for anyone looking to do this with Rust and Alpine.
As pointed out, the issue comes from trying to use the default
x86_64-unknown-linux-gnu
to compile the Rust binary. Instead, compile withx86_64-unknown-linux-musl
and in particular use:rustup target add x86_64-unknown-linux-musl
Followed by:
cargo build --release --target=x86_64-unknown-linux-musl
Then add this new binary to the project instead of the old one, and now Alpine will run it just fine.
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: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:
And compile it on my glibc system, then try running it under Alpine, we see:
If we make the expected interpreter available, like this:
We get a new error:
If we make the necessary shared library available:
Then the command works as expected: