Search code examples
ruby-on-railspostgresqlherokuruby-on-rails-5rake-task

Rake tasks and migration on Heroku without downtime


Context

I'm using Heroku to serve my rails API (v5.2) with a PostgreSQL database,

Frequently, after some migrations, I have to manually run some specific rake tasks.

Those rake tasks typically delete all the rows of a table before recreating them with different data.

This is problematic for me because it create a downtime for approx. 20 minutes, twice a week (by turning on and off Maintenance mode).

Problem

I would like to avoid downtime between my migrations.

Intended solution

for this, I planned on using Heroku preboot alongside release phase tasks.

After activated preboot for my app, I will put a script in my Procfile

release: ./release-tasks.sh

And in the release-tasks.sh file something like:

heroku run rake my_rake_task --app myApp

Questions

  • Is it a good/ok solution?

  • Is it sure that during the migration phase, users will be able to query the "old" database before the new one is live?

  • Is there a way to activated release scripts on demand? (e.g using an env var in Heroku? -- I won't need it for every migrations).


Solution

  • This is a good solution, yes. Release Phase is meant exactly to help running migrations whenever the app is deployed.

    This won't prevent downtime in your specific case though. Release phase doesn't start a new database with every release. It just runs a one-off dyno with your command.

    Your only solution here is to change your migration strategy to avoid deleting and recreating everything. Depending on what you're doing, you may be able to just update/add/remove the data you need.
    Or you could create a new temporary table with the new data, and then delete the old table and rename the new one to its permanent name.
    Both those solutions are something you need to write your own code for though.