I did some work to reproduce this locally and while I can’t prove it exactly, I’m willing to bet that there’s a versioning difference between elixir:alpine and alpine:latest. If I change the second FROM statement to elixir:alpine, it works fine. I’ll do some more digging (because I’m curious), but that seems like a plausible reason to me. Not sure why you’re getting a “no such file or directory” error, though.
I think I know the problem here. alpine uses musl OOTB, while most others use glibc. I cannot reproduce your problem exactly (the only way I was able to do so was by setting the build_stage FROM to elixir, which is actually Debian based), however, in that situation, I was able to do some poking. If I straceerlexec – since as you point out, it does exist – I see the following
execve("/opt/elixir_hello_world/erts-13.1.4/bin/erlexec", ["/opt/elixir_hello_world/erts-13."...], 0x7ffd6d09ac30 /* 6 vars */) = -1 ENOENT (No such file or directory)
What I suspect is going on (but is hard to pin down given I can’t fully recreate your problem) is that glibc is being brought into your container somehow (are you perhaps copying _build from your local machine when you build the release? it may be worth adding that to .dockerignore), which is causing you problems when you move onto a glibc-less system (i.e. alpine:latest). When I build the release on elixir:alpine, I see that erlexec is correctly linked to libmusl