I have an executable created via mix release
which works just fine when I run it with start
on my local machine. However, my docker image crashes when trying to start
the executable and I don't know why.
FROM elixir:1.10
# Install Hex + Rebar
RUN mix do local.hex --force, local.rebar --force
COPY . /
WORKDIR /
ENV MIX_ENV=prod
RUN mix do deps.get --only $MIX_ENV, deps.compile
RUN mix release
EXPOSE 8080
ENV PORT=8080
ENV SHELL=/bin/bash
CMD ["_build/prod/rel/my_app/bin/my_app", "start"]
This is my docker file. It does nothing special other than compiling and then trying to run the release via start
.
However, when I execute the docker image with docker run -p 8080:8080 my-app:1.0
docker crashes:
/_build/prod/rel/my_app/releases/0.1.0/../../erts-10.5/bin/erl: 12: exec: /_build/prod/rel/my_app/erts-10.5/bin/erlexec: Exec format error
At first I thought this was happening because the file _build/prod/rel/my_app/bin/my_app
was missing #!/usr/bin/env bash
at the top (after reading some SO questions).
While indeed it doesn't have that, it has something else that should equally work: #!/bin/sh
So this theory is out.
Is something wrong with my Dockerfile? How can I get rid this error?
This was a tricky one. After reading other similar questions (and the comments from @potibas and @Stefano) I found out what was happening.
So, as I have said, the release file works well on my local machine. This happens because in my local machine the files were being compiled to its operative system (OS).
Now, the docker VM does not have the same OS as my local machine. This matters because of this line:
COPY . /
Here I am copying everything from the workdir to docker. Including the binaries and dependencies compiled for my local machine's OS.
This caused the issue above mentioned.
There are 2 possible solutions.
_build
and deps
folders from the image after the COPY
command, via RUN rm -r _build
and RUN rm -r deps/
..dockerignore
file.I personally opted for the second option, as it allows me to have a leaner image.