Docker run error 'exec format error' after multi-stage build

Hi, I have a seemingly standard Dockerfile:


FROM ocaml/opam:ubuntu-20.04-ocaml-4.13@sha256:43d0c6294965bbd51282eb1328c3fd45430a44c4581b7357a9eb4f25731c57cb as build

RUN sudo apt-get install -y libev-dev libssl-dev libsqlite3-dev pkg-config
ADD . .
RUN opam init
RUN opam exec -- opam install --deps-only -y .
RUN sudo chown -R opam .
RUN opam exec -- dune build --release


FROM ubuntu:20.04@sha256:7c9c7fed23def3653a0da5bc9ecb651efe155ebd5802c7ba5d585edaa6c89496
COPY --from=build /home/opam/zk/_build/default/bin/bin.exe ./zk.exe
COPY --from=build /home/opam/zk/css ./css/
COPY --from=build /home/opam/zk/js ./js/

CMD ["/zk/zk.exe"]

I build it with:

docker build -t zk:latest .

And run with:

docker run zk:latest

However I get an error on run:

standard_init_linux.go:228: exec user process caused: exec format error

I read that this is caused by an arch mismatch, however I chose specific Ubuntu base images after checking they were all Ubuntu 20.04, on linux/amd64. And I’m specifically copying and running the .exe that dune produces, so there should be no issue with that.

Another interesting clue: even the build stage errors when trying to run the same executable it just built:

docker run -it zk-build:latest /bin/sh
$ ls
_build	css	      js   migration	      package.json	  zk.install  zk.opam.template
bin	dune-project  lib  package-lock.json  tailwind.config.js  zk.opam
$ ./_build/default/bin/bin.exe
/bin/sh: 2: ./_build/default/bin/bin.exe: Exec format error

Any ideas what’s going on?

Found the culprit, it was the --release flag to dune, without it the exe is able to run.

Why does --release produce what I presume is a library instead of an executable? Not sure.