I’m building a release with Distillery and then deploying the archive. After running bin/app start, I’m running migrations in a post_start-hook. The problem I have is that sometimes it errs on “Node is not running!”:
rope@web-001:~/apps/rope/bin$ rope start
Running migrations
ok
Migrations ran successfully
rope@web-001:~/apps/rope/bin$ rope start
Running migrations
Node is not running!
rope@web-001:~/apps/rope/bin$ rope start
Running migrations
ok
Migrations ran successfully
rope@web-001:~/apps/rope/bin$ rope start
Running migrations
Node is not running!
The post_start-hook looks like this:
defmodule Release.Tasks do
def migrate do
{:ok, _} = Application.ensure_all_started(:rope)
path = Application.app_dir(:rope, "priv/repo/migrations")
Ecto.Migrator.run(Rope.Repo, path, :up, all: true)
:init.stop()
end
end
I’ll follow up in the morning when I’m more awake, but your post is missing the content of the hook shell script which executes the module you showed. I’m assuming your hook is using bin/yourapp rpc... to connect to the node and run the migrate function, but the call to init:stop would kill the node, so I’m assuming I’m missing something. Is this module in an escript which is executed?
In any case, if you are using rpc, you’ll need to give a short time for the node to actually start before running the rpc call, introducing a sleep of around 1 second should be enough, but that race is more than likely what’s causing it to fail randomly.
If you could clarify how you are using the hook, that would help a bunch!
The application would only fail to start when it can not connect to the DB. Whatever structure the database has is of no concern to the application, as long as it doesn’t try to do something with it.
So right after starting the application is the only moment you can run the migrations, as it needs that DB-connection from the application.
[quote=“ddf, post:7, topic:1232, full:false”]… as long as it doesn’t try to do something with it.
[/quote]
This is not always the case. The app may start some background tasks that may need some DB tables and/or load some data from the DB to start working. With SQLAlchemy this is partly solved by calling enging.create_all() at start which is idempotent. At least it won’t complain about absent tables.