Trouble deploying Elixir app using Distillery

Hello all. I’m trying to deploy and elixir app build with Phoenix using distillery. When I compile it and build my release it all looks good and will run as expected on my docker container. However when I put this artefact on the EC2 instance that I intend on hosting it on I get the below error:

    Application is up!
Running migrations
** (Protocol.UndefinedError) protocol Enumerable not implemented for {:gen_server, :call, 
[#PID<11086.3551.0>, {:checkout, #Reference<11086.2617215781.3000500225.137934>, true, 
:infinity}, 5000]}
    (elixir) lib/enum.ex:1: Enumerable.impl_for!/1
    (elixir) lib/enum.ex:141: Enumerable.reduce/3
    (elixir) lib/enum.ex:2979: Enum.map_join/3
    (elixir) lib/exception.ex:572: Exception.format_stacktrace/1
    (elixir) lib/exception.ex:145: Exception.format/3
    (distillery) lib/mix/lib/releases/runtime/control.ex:643: Mix.Releases.Runtime.Control.rpc/2
    (distillery) lib/entry.ex:44: Mix.Releases.Runtime.Control.main/1
    (stdlib) erl_eval.erl:680: :erl_eval.do_apply/6

I’m finding this stack track really hard to read. Any support in figuring out what the cause of this would be a life saver. I’ve been banging my head against this for the past few days and I can’t seem to resolve it no matter what I try.

Thank you all very much.

Have you configured your DB connection properly. Looks like you get a crash when a new DB connection is being checked out to run migrations.

Are you using env variables in your config/prod.exs? It could be that they are looked up at build time instead of run time. Any info on how you configure your external services (like DB) and how you run the release will help diagnose the problem better.

1 Like

Do you have a GenServer with a handle_call method for something called “checkout”? It looks like you’re getting an error there.

I’m guessing on your EC2 instance, you have something that’s different. For example, maybe you’re calling an external API and you’re expecting to get back a list, but somehow it’s returning nil on the EC2 instance. This is just a guess … it’s hard to say without knowing what’s in the “checkout” call.

1 Like

Ecto has it … Just as @alco has already suggested, the problem is probably with the migrations setup.

It’s also a bug in distillery, since the stacktrace should be printable, and here it’s not.

1 Like

@idiot @alco thank you for your support. I’ll raise an issue with distillery and try to figure out why ecto is failing. I’ll look in to the migrations setup.

Huh, it’s weird to me that the stacktrace includes lib/exception lines… it almost looks like the error message you’re seeing comes from an error while trying to handle another error. So I wonder if the Protocol.UndefinedError is a red herring and the “real” error is lib/mix/lib/releases/runtime/control.ex:643: Mix.Releases.Runtime.Control.rpc/2. What’s that line?

On a side note, how have you set up migrations to run? My phoenix app, too, uses distillery and runs on AWS in a docker container, and I haven’t figured out a way yet that I’m happy with. Ultimately, I just added an Ecto.Migrator.run call in my application’s startup callback, but I feel like there’s got to be a better way. The distillery docs show how to set up a bin/myapp migrate command, but I couldn’t figure out how to have the docker start up run both that and the bin/myapp foreground one.

You can use bin/myapp migrate in a pre-start distillery hook if you want. Or you can migrate the database in some other process (like an orchestrator), by executing bin/myapp migrate via docker exec or whatever it is called.

1 Like

@losvedir I’ve set up my migrations by following this tutorial here, it works great for me. As @idiot said it’s using a hook but this is a post_start hook instead:

2 Likes