Ecto migration fails on Heroku

ecto
phoenix
deployment

#1

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:


#2

Can you post the error message that you receive?


#3

Sure, fixed that.


#4

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


#5

Also please let us know your Ecto version.


#6

@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.


Heroku Deployment Woes
#7

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:


#8

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


#9

glad i ran into this post here. this is kind of unfortunate since I was following the exact steps from Phoenix docs https://hexdocs.pm/phoenix/heroku.html.

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.

Thanks again for all the work!


#10

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.


#11

fyi: there is a PR inbound https://github.com/phoenixframework/phoenix/pull/3280 that adds this crucial step to the docs…


#12

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?


#13

just checked:

short answer yes it needs to published for users of the “hashnuke/elixir” buildpack - publish instructions https://devcenter.heroku.com/articles/buildpack-registry#publishing-a-buildpack-version for whoever is in control of the buildpack on heroku…

creating new app heroku create --buildpack hashnuke/elixir which is in the heroku docs (https://elements.heroku.com/buildpacks/hashnuke/heroku-buildpack-elixir)

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 “https://github.com/HashNuke/heroku-buildpack-elixir.git” - https://hexdocs.pm/phoenix/heroku.html#creating-the-heroku-application (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…


#14

thx for the commit @josevalim :heart::blue_heart::purple_heart: as always!

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…


#15

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


#16

merged - https://github.com/phoenixframework/phoenix/commit/9a758347ce7a34b97499ed374f12cee9eef5da7a

now it’s just the issue of getting the changes to show up on https://hexdocs.pm/phoenix/heroku.html

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


#17

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: