Understanding my current docker setup, trying to use Argon2

So I have a fairly simple Dockerfile that looks like:

FROM elixir:latest

RUN mkdir /app
COPY . /app
WORKDIR /app

RUN mix local.hex --force
RUN mix deps.get --only prod
RUN MIX_ENV=prod mix compile
RUN mix phx.digest
#RUN MIX_ENV=prod mix ecto.create
#RUN MIX_ENV=prod mix ecto.migrate
CMD MIX_ENV=prod mix phx.server

I am using Argon2, and on my dev server I see this error when it tries to encrypt a password:

[error] Process #PID<0.402.0> raised an exception
** (RuntimeError) An error occurred when loading Argon2.
Make sure you have a C compiler and Erlang 20 installed.
If you are not using Erlang 20, either upgrade to Erlang 20 or
use bcrypt_elixir (version 0.12) or pbkdf2_elixir.
See the Comeonin wiki for more information.

    (argon2_elixir) lib/argon2/base.ex:19: Argon2.Base.init/0
    (kernel) code_server.erl:1340: anonymous fn/1 in :code_server.handle_on_load/5
** (UndefinedFunctionError) function Argon2.Base.hash_password/3 is undefined (module Argon2.Base is not available)
    (argon2_elixir) Argon2.Base.hash_password("hello123", <<212, 122, 223, 217, 68, 96, 51, 247, 99, 9, 182, 11, 161, 23, 5, 82>>, [])
    (comeonin) lib/comeonin/base.ex:88: Comeonin.Argon2.add_hash/2
    (realtime) lib/realtime/identity/identity.ex:112: Realtime.Identity.encrypt_password/1
    priv/repo/seeds.exs:113: (file)
18:24:42.925 [warn] The on_load function for module Elixir.Argon2.Base returned:
{%RuntimeError{message: "An error occurred when loading Argon2.\nMake sure you have a C compiler and Erlang 20 installed.\nIf you are not using Erlang 20, either upgrade to Erlang 20 or\nuse bcrypt_elixir (version 0.12) or pbkdf2_elixir.\nSee the Comeonin wiki for more information.\n"}, [{Argon2.Base, :init, 0, [file: 'lib/argon2/base.ex', line: 19]}, {:code_server, :"-handle_on_load/5-fun-0-", 1, [file: 'code_server.erl', line: 1340]}]}

How do I determine what version of Erlang I am using?

Looking at the elixir dockerfile I can see it says Erlang:21.
Do I need to add a C compile as a dep in my dockerfile somehow?

1 Like

Yeah for the C compiler question. The better option would be to do a two stage dockerfile with the first one using one of the elixir-dev type images which will have everything you need included already.

1 Like

I’m wondering why this compiles at all…

Before building the image the next time, please make sure, you have a .dockerignore file with the following content:

deps
_build

I fear that the compiled version of your dev machine ended up in the docker image and therefore created a version mismatch between your hosts and the images erlang versions.

Edit

After that has been done, you are ready to migrate to a proper multistage build, beeing sure no compiled artifacts from the host compromise any of your guests.

6 Likes

I added that to my build process and now I am getting a different error during the docker build stage:

“Compiling 1 file (.ex)”, “Generated jumper app”, “==> realtime”, “Could not find "rebar3", which is needed to build dependency :parse_trans”, “I can install a local copy which is just used by Mix”, “Shall I install rebar3? (if running non-interactively, use "mix local.rebar --force") [Yn] \u001b[91m** (Mix) Could not find "rebar3" to compile dependency :parse_trans, please ensure "rebar3" is available”, “\u001b[0m”]}

Any good examples of a multistage build on e.g. github that I can reference?

That one is fixable by reading the message and adding mix local.rebar --force to the script :wink:

And no, I have no good examples of a multistage docker file, as most I know do make the same mistakes again and again…

But if you do not fear switching to distillery, you can use its “deploy to docker” guides as a starter.

1 Like

Are you installing rebar? Try swapping your mix local.hex --force line for

RUN mix local.rebar --force && \
        mix local.hex --force
1 Like

I am not explicitly using rebar, but I guess it is a dependancy from one of mix libs.

The distillery 2.0 documentation has a two stage example.

1 Like

Maybe I should just use distillery, not sure of the benefits over my current docker setup but I will look into it now more thanks.

I did a sample project a while ago to try distillery and docker, in case you want to check it out, it’s based on the distillery documentation. Multistage builds are the best way to build for docker

2 Likes