Ecto migration fails on Heroku

I’ve got a new app deployed to Heroku and am unable to get the Repo application to start.

In prod.exs:

use Mix.Config


config :testapp, TestappWeb.Endpoint,
  url: [scheme: "https", host: System.get_env("BASE_URL"), port: 443],
  force_ssl: [rewrite_on: [:x_forwarded_proto]],
  http: [:inet6, port: System.get_env("PORT") || 4000],
  cache_static_manifest: "priv/static/cache_manifest.json",
  secret_key_base: Map.fetch!(System.get_env(), "SECRET_KEY_BASE")

# Do not print debug messages in production
config :logger, level: :info

config :testapp, Testapp.Repo,
  url: System.get_env("DATABASE_URL"),
  pool_size: String.to_integer(System.get_env("POOL_SIZE") || "10"),
  ssl: true

[...snip...]

But trying to connect to the app or run ecto.migrate gives the following error:

** (EXIT from #PID<0.74.0>) an exception was raised:
      ** (ArgumentError) supervisors expect the child to be a module, a {module, arg} tuple or a map with the child specification, got:
       {DBConnection.ConnectionPool, {Ecto.Repo.Supervisor, :start_child, [{DBConnection.ConnectionPool, :start_link, [{Postgrex.Protocol, [types:
        Postgrex.DefaultTypes, repo: Testapp.Repo, telemetry_prefix: [:Testapp, :repo], otp_app: :Testapp, timeout: 15000, pool_timeout: 5000, adapter:
         Ecto.Adapters.Postgres, ssl: true, pool_size: 2, username: "...", password: "...", database: "...", hostname: "...", port: 5432, pool:
          DBConnection.ConnectionPool]}]}, Ecto.Adapters.Postgres, #Reference<0.280083182.1810497537.168308>, %{opts: [timeout: 15000, pool_timeout: 5000,
           pool_size: 2, pool: DBConnection.ConnectionPool], sql: Ecto.Adapters.Postgres.Connection, telemetry: {:debug, [], [:Testapp, :repo, :query]}}]},
            :permanent, 5000, :worker, [DBConnection.ConnectionPool]}
        (elixir) lib/supervisor.ex:609: Supervisor.init_child/1
        (elixir) lib/enum.ex:1255: Enum."-map/2-lists^map/1-0-"/2
        (elixir) lib/supervisor.ex:581: Supervisor.init/2
        (stdlib) supervisor.erl:294: :supervisor.init/1
        (stdlib) gen_server.erl:365: :gen_server.init_it/2
        (stdlib) gen_server.erl:333: :gen_server.init_it/6
        (stdlib) proc_lib.erl:247: :proc_lib.init_p_do_apply/3a

Any suggestions as to what I might be doing wrong or overlooking? As far as I can tell I’ve followed the Phoenix Heroku setup instructions correctly.

Edit: added error instead of another copy of the config file :man_facepalming:

Can you post the error message that you receive?

Sure, fixed that.

What is your Elixir version configured on Heroku? Are you on latest?

Also please let us know your Ecto version.

@josevalim Turns out it was Elixir 1.5.0. I’ve upgraded to Erlang 21.1.2 & Elixir v1.7.4 and it now works as expected.

Also, it was ecto 3.0.3 & ecto_sql 3.0.2.

I thought it was the Elixir version because I remembered Elixir v1.5.0 had a bug where the tuple child specs were not allowed at some positions. :slight_smile:

It would probably have taken me a long time to have thought to check that. Thanks for your help!

glad i ran into this post here. this is kind of unfortunate since I was following the exact steps from Phoenix docs Deploying on Heroku — Phoenix v1.8.8.

This guide does not mention elixir_buildpack.config file how to set the Erlang and Elixir versions on heroku. I found this instruction to be most useful and successfully deployed the app.
https://github.com/HashNuke/heroku-buildpack-elixir#configuration

Thanks again for all the work!

For anyone else that runs into this, the solution I found (using the link from @baskint) was to put a file in the root of the project named elixir_buildpack.config and put the following inside:

elixir_version=(branch master)

This sets the elixir version to the latest supported by the build pack, so if you need it to be more explicit than that you can specify but this solved the issue for me.

fyi: there is a PR inbound Add elixir_buildpack.config to Heroku documentation by mcelaney · Pull Request #3280 · phoenixframework/phoenix · GitHub that adds this crucial step to the docs..

We have merged a commit to the buildpack that makes it use v1.5.3. Do we need to publish the buildpack anywhere? Or just having the fix in master is enough?

just checked:

short answer yes it needs to published for users of the “hashnuke/elixir” buildpack - publish instructions Heroku Buildpack Registry | Heroku Dev Center for whoever is in control of the buildpack on heroku..

creating new app heroku create --buildpack hashnuke/elixir which is in the heroku docs (HashNuke/heroku-buildpack-elixir - Buildpacks - Heroku Elements)

which leads to the app having this buildpack https://buildpack-registry.s3.amazonaws.com/buildpacks/hashnuke/elixir.tgz which is from july 2018 (eg. not containing recent fix/bump)

note: the phoenix guides instructs one to use edge eg heroku create --buildpack “GitHub - HashNuke/heroku-buildpack-elixir: Heroku Buildpack for Elixir with nitro boost · GitHub” - Deploying on Heroku — Phoenix v1.8.8 (so publish issue is limited to a large degree)

above PR which is now merged should perhaps be changed - I would perhaps note on dev/prod parity and configuring the erlang/elixir versions to match…

thx for the commit @josevalim :heart::blue_heart::purple_heart: as always!
https://github.com/phoenixframework/phoenix/commit/2eed5f8918c272517d8194e10a8e869a27664fcc

I wonder if for longevity reasons and dev/prod parity reasons that configuring erlang_version should be encouraged as well..

eg write “Elixir and Erlang version” in the text - and add erlang_version=21.2.5 (or 20.3.8.8?) to the suggested elixir_buildpack.config content..

just say the word if you want me to PR that..

Agreed, please do send a PR. I think 21.2.5 is good enough for now. We can also update Elixir to v1.8.1. <3

merged - Update heroku.md (#3286) · phoenixframework/phoenix@9a75834 · GitHub

now it’s just the issue of getting the changes to show up on Deploying on Heroku — Phoenix v1.8.8

(eg remember to backport it to the 1.4 branch, for next patch release - I assume..)

Hi all! If you’d like a little more control over your Elixir version and such on Heroku you can now use a Dockerfile rather than a Heroku buildpack for deploying your app. We’ve been using it at Waive and it’s working very well :slight_smile: