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