0

Background

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.

Docker

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.

Error

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

Research

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.

Question

Is something wrong with my Dockerfile? How can I get rid this error?

Flame_Phoenix
  • 16,489
  • 37
  • 131
  • 266
  • could `ENV SHELL=/bin/bash` require bash instead of `#!/bin/sh` ? – jp-jee Nov 03 '20 at 15:14
  • 1
    Not sure if it's the case here, but have you added `/_build/` to the .dockerignore file? I remember some time ago having problems mixing build files from development machine (mac) and inside docker (linux). – potibas Nov 03 '20 at 15:19
  • 1
    it looks like a problem with the architecture used to create the image and the architecture used to run the container. – Stefano Nov 03 '20 at 15:23

1 Answers1

3

RCA

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.

Solution

There are 2 possible solutions.

  1. Remove the _build and deps folders from the image after the COPY command, via RUN rm -r _build and RUN rm -r deps/.
  2. Add the mentioned folders as well as all the non-essential files to a .dockerignore file.

I personally opted for the second option, as it allows me to have a leaner image.

Flame_Phoenix
  • 16,489
  • 37
  • 131
  • 266
  • This worked for me, thank you! I used the `.dockerignore` approach as well. I can add that you could also specifically cherry pick folders to `COPY` - might result in a less "lean" Dockerfile, but you have all the control. – voiarn Sep 05 '22 at 08:42