How to rollback database in docker container using elixir phoenix releases and the example MyApp.Release.rollback in the guides How to rollback database in docker container using elixir phoenix releases and the example MyApp.Release.rollback in the guides docker docker

How to rollback database in docker container using elixir phoenix releases and the example MyApp.Release.rollback in the guides


In the first place, rpc call should succeed. Make sure you indeed have the migration in the question up before running my_app rpc. Note, that the second argument is the version to revert to, not the migration to revert.

Regarding the eval. One should start or at least load the application before any attempt to access its config. As per documentation:

You can start an application by calling Application.ensure_all_started/1. However, if for some reason you cannot start an application, maybe because it will run other services you do not want, you must at least load the application by calling Application.load/1. If you don't load the application, any attempt at reading its environment or configuration may fail. Note that if you start an application, it is automatically loaded before started.

For the migration to succeed, one needs Ecto aplication Ecto.Adapters.SQL.Application started and your application loaded (to access configs.)

That said, something like this should work.

def my_rollback(version) do  Application.load(:my_app)  Application.ensure_all_started(:ecto_sql)  Ecto.Migrator.with_repo(MyApp.Repo,    &Ecto.Migrator.run(&1, :down, to: version))end

And call it as

./my_app eval 'MyApp.Release.my_rollback(20191106071140)'

Still, rpc should start the required applications out of the box (and it indeed does, according to the message you get back,) so I’d suggest you to triple-check the migration you are requesting to down is already up and you pass the proper version to downgrade to.


There were two issues here and thanks to @aleksei-matiushkin I got it working.

The first issue was not having Application.load(:my_app) in the function.

The second issue was that I was calling the rollback functions (both mine and @aleksei-matiushkin) as a string and not an int. Now I call it like: ./my_app eval 'MyApp.Release.my_rollback(20191106071140)'

The file now looks like this:

defmodule MyApp.Release do  @app :my_app  def migrate do    for repo <- repos() do      {:ok, _, _} = Ecto.Migrator.with_repo(repo, &Ecto.Migrator.run(&1, :up, all: true))    end  end  def rollback(repo, version) do    setup_for_rollback()    {:ok, _, _} = Ecto.Migrator.with_repo(repo, &Ecto.Migrator.run(&1, :down, to: version))  end  def my_rollback(version) do    setup_for_rollback()    rollback(MyApp.Repo, version)  end  defp setup_for_rollback() do    Application.load(@app)    Application.ensure_all_started(:ecto_sql)  end  defp repos do    Application.load(@app)    Application.fetch_env!(@app, :ecto_repos)  endend

I am not sure if this is an idiomatic implementation. I did not have any issues excluding Application.ensure_all_started(:ecto_sql) but since it was recommended I guess I'll leave it in.