I am using Elixir 1.9 and it’s release structure to deploy a Phoenix application, and I’m having some trouble getting migrations to trigger on start of the application. So far, I’ve been manually running a migration task within a module before running start, but I’m hoping for a more modular solution.
I noticed that that MixRelease struct has a :boot_scripts
field. However, I can’t find any examples on exactly how it should be used. I was wondering if it would help me bundle any pre-launch tasks though within my application cleanly, and how exactly I could do that. Could anyone advise me?
Thank you.
If you are looking for a good example of performing DB migrations, you can leverage the work done in hex.pm as a reference: https://github.com/hexpm/hexpm/blob/master/lib/hexpm/release_tasks.ex#L36
And then run the release task defined function via eval
as seen in this section of the docs: https://hexdocs.pm/mix/Mix.Tasks.Release.html#module-one-off-commands-eval-and-rpc
3 Likes
I currently have this, which I believe is similar.
def migrate do
start_services()
path = Application.app_dir(:my_app, "priv/repo/migrations")
IO.puts "Running migrations: #{path}"
Migrator.run(Repo, path, :up, all: true)
IO.puts "Ran migrations successfully."
stop_services()
end
defp start_services do
Application.load(:my_app)
IO.puts("Starting dependencies..")
# Start apps necessary for executing migrations
Enum.each(@start_apps, &Application.ensure_all_started/1)
# Start the Repo(s) for app
IO.puts("Starting repos..")
Enum.each(@repos, & &1.start_link(pool_size: 1))
end
Is there any way to ensure this is always invoked though at boot time? I was under the impression it’s possible to tie this together with /bin/my_app start
so that I don’t have to call separate commands.
I might just be mistaken on the best practice as far as this goes, however.
If you want to ‘always’ call it on boot, then just put it in a gen_server that is launched after the DB loads in the dependency tree, and then return from the start when the migration is complete, then you can just shut the gen_server down (transient or temporary or so).
1 Like
This sounds like a really good solution, thank you!
1 Like