Problems deploying argon2_elixir

I am the maintainer of Comeonin (and its password hashing dependencies).

Several users are having problems deploying argon2_elixir, as can be seen in this issue. It seems that there are no problems with bcrypt_elixir.

If anyone is successfully deploying argon2_elixir, we would love to hear from you :slight_smile: Hopefully, you can help resolve this issue.

5 Likes

I managed to compile it after updating Erlang / OPT to version 20.

2 Likes

The problem people are reporting is that their dev builds work, but the production build doesn’t, and it seems they’re using Distillery. :slight_smile:

1 Like

Just want to chime in and say that I’ve reviewed the thread, and I don’t believe the issue lies with Distillery. If there was a general issue with NIFs, we’d see it in other cases, but we don’t. Rather curiously, even between two very similar libraries (bcrypt_elixir and argon2_elixir), only the latter exhibits this behaviour. I’m suspicious that there is something wrong with the NIF code itself, but I haven’t had time to look at it, but the error definitely seems to indicate that the NIF is violating some invariant.

4 Likes

Can someone explain why would a dev build work, but a prod release fail please?
It really bothers me in a “Can I depend on this thing” kind a way :slight_smile:

1 Like

Many reasons, like if it builds a nif but not storing it in priv, not getting compiled, not getting copied into the release, etc… etc…

2 Likes

Wonderful :slight_smile:
Is this a Distillery specific problem or release problem in general?

1 Like

Releases in general, they are designed to be small packed distributions with no extra stuff. :slight_smile:
It’s not even a problem, it is just by design, just all libraries should do things right or they break, expectedly. ^.^

2 Likes

You’re making the assumption that this is even caused by releases in the first place. Based on that thread, it’s not clear to me whether people are running into this issue because they are taking a release and dropping it on another host which is missing system dependencies, or same OS but different kernel versions, or different versions of ERTS. When it comes to NIFs, extra care is required, this is a downside of using NIFs, but the tradeoff of course is better performance. You have to make sure your dev and prod machines match OS, compatible kernel versions, matching system dependencies and versions (i.e. musl/libc, OpenSSL, etc.), and ensure that the NIF is compiled for a target triple which matches the host (i.e. deploying something compiled for a specific CPU will almost certainly break if dropped somewhere else, but typically targets aren’t specified to that degree unless you are compiling for embedded devices).

If all of these things have been covered and there is still an issue, then either the NIF is written incorrectly, or there is a new edge case related to releases and NIFs. There are a very large number of projects deploying via Distillery/using releases, and I suspect the vast majority of them use at least one NIF - so if this was an issue with Distillery specifically, or even releases more generally, we would expect to have seen this come up already. Since that isn’t the case, I’m very suspicious that either one of the prerequisites have been missed, or there is a fundamental issue with the NIF itself, and based on the error we see, it could be either one of them. While I won’t be so foolish as to say that releases are infallible, they are certainly reliable enough that questioning them should be near the end of your list of suspects, just above Erlang/OTP itself.

Releases are a fundamental part of Erlang/OTP, and have been around since the very beginning - they’ve had over 20 years of use to uncover issues and get them resolved. Distillery itself is obviously newer than that, but has been around in some form or another for the past 4+ years and has seen a pretty wide array of deployments itself, we certainly would know if there was a reliability issue with NIFs by now :wink:

5 Likes

Quick update: I have made changes to the Makefile (removed some of the optimization options), and I’m waiting for feedback on those changes.

2 Likes

Problem solved :smile:

Simplifying the Makefile, along with a couple of other minor changes to the NIF code, (in version 1.2.13) seems to have solved the problem.

If anyone here was having issues creating a release, please update to 1.2.13.

5 Likes

what about this…

$ iex -S mix
==> argon2_elixir
could not compile dependency :argon2_elixir, “mix compile” failed. You can recompile this dependency with “mix deps.compile argon2_elixir”, update it with “mix deps.update argon2_elixir” or clean it with “mix deps.clean argon2_elixir”
==> Project
** (Mix) “nmake” not found in the path. If you have set the MAKE environment variable,
please make sure it is correct.

I’m having trouble with this… trying to build for Docker deployments (per our company’s DevOps requirements).

I get an error like the following on startup:

crash_report #{label=>{proc_lib,crash},report=>[[{initial_call,{supervisor,kernel,[‘Argument__1’]}},{pid,<0.2040.0>},{registered_name,[]},{error_info,{exit,{on_load_function_failed,‘Elixir.Argon2.Base’},[{init,run_on_load_handlers,0,[]},{kernel,init,1,[{file,“kernel.erl”},{line,212}]},{supervisor,init,1,[{file,“supervisor.erl”},{line,295}]},{gen_server,init_it,2,[{file,“gen_server.erl”},{line,374}]},{gen_server,init_it,6,[{file,“gen_server.erl”},{line,342}]},{proc_lib,init_p_do_apply,3,[{file,“proc_lib.erl”},{line,249}]}]}},{ancestors,[kernel_sup,<0.2014.0>]},{message_queue_len,0},{messages,[]},{links,[<0.2016.0>]},{dictionary,[]},{trap_exit,true},{status,running},{heap_size,376},{stack_size,27},{reductions,273}],[]]}

This is using

{:comeonin, "~> 5.0"},
{:argon2_elixir, "~> 2.0"},

in an umbrella app using distillery {:distillery, "~> 2.0.12", runtime: false}

How many cores are you using? You need to use more than one.
For docker deployments, you will also probably need to reduce the m_cost.
Finally, you can remove the comeonin line from your mix.exs file.
Let me know how you get on.

Sorry to be clueless, but how do I deduce the m_cost? Is that a config value somewhere?

As for cores, I don’t know. The Docker Daemon on Mac I have configured to use 4 CPUs, but I don’t know if that will be equivalent.

For information about choosing the m_cost (memory allocation), see https://hexdocs.pm/argon2_elixir/Argon2.Stats.html - you can set the value in the config file (you will probably need to reduce it to 16 or 15).

And here is some information about using Docker with argon2_elixir - https://github.com/riverrun/comeonin/wiki/Deployment

Also, how much memory is your server / docker instance going to have?

I think I got this worked out… not really sure what the hiccup was… I was working through a lot of Docker issues, now everything seems to be coming up clean.

Great to hear you got it working

1 Like