Hot deploy on Heroku with no downtime

10,881

Solution 1

You could setup a second Heroku app which points to the same DB as your primary production app and use the secondary app to run your DB migrations without interrupting production (assuming the migrations don't break the previous version of your app).

Let's call the Heroku apps PRODUCTION and STAGING.

Your deploy sequence would become something like:

  1. Deploy new code to STAGING
    git push heroku staging
  2. Run database migrations on STAGING (to update PROD db)
    heroku run -a staging-app rake db:migrate
  3. Deploy new code to PRODUCTION
    git push heroku production

The staging app won't cost you anything since you won't need to exceed Heroku's free tier and it would be pretty trivial to setup a rake deploy script to do this for you automatically.

Good luck!

Solution 2

If you're able to live with two versions of the same app live at the same time, Heroku now has a preboot feature.

https://devcenter.heroku.com/articles/preboot

Solution 3

The only method to improve the process somewhat is what this guy suggests. This is still not a hot deploy scenario though:

http://casperfabricius.com/site/2009/09/20/manage-and-rollback-heroku-deployments-capistrano-style/

One thing I would suggest is pushing only your migrations up to Heroku first and running them before you push your codebase. This would entail committing the migrations as standalone commits and manually pushing them each time (which is not ideal). I'm very surprised there is not a better solution to this issue with all of the large apps hosted on Heroku now.

Solution 4

You actually will have some downtime when Heroku restarts your app. They have a new feature called Preboot that starts up new dynos before taking out the old ones: https://devcenter.heroku.com/articles/labs-preboot/

As for database migrations, that article links to this one on how to deal with that issue: http://pedro.herokuapp.com/past/2011/7/13/rails_migrations_with_no_downtime/

Solution 5

I first commit the migrations, run them, then push the rest of the code. Add a single file like so:

git commit -m 'added migration' -- db/migrate/2012-your-migration.rb
Share:
10,881
zetarun
Author by

zetarun

Updated on June 28, 2022

Comments

  • zetarun
    zetarun almost 2 years

    A bad side of pushing to Heroku is that I must push the code (and the server restarts automatically) before running my db migrations.

    This can obviously cause some 500 errors on users navigating the website having the new code without the new tables/attributes: the solution proposed by Heroku is to use the maintenance mode, but I want a way with no downside letting my webapp running everytime!

    Is there a way? For example with Capistrano:

    • I prepare the code to deploy in a new dir
    • I run (backward) migrations and the old code continue to work perfectly
    • I swith mongrel instance to the new dir and restart the server

    ...and I have no downtime!