Heroku deploy script (for Rails)

On the face of it, deploying a Rails app to Heroku is very simple. You just push your Git repository to the master branch of your repository on Heroku, then sit back and watch:

$ git push heroku master

Heroku will detect that your repository contains a Rails app, do a bit of house keeping, and restart your web servers for you.

But... (there's always a "but") Heroku won't run your migrations automatically. You'll need to do that yourself, like this:

$ heroku run rake db:migrate

And if you need to run migrations, any requests that reach your app before the migrations have been run could fail when Rails fails to find the right things in your database. You'll want to:

  1. Push the new code.
  2. Put the app into maintenance mode.
  3. Run the migrations.
  4. Disable maintenance mode.

If you've setup a second Heroku app to serve as a staging server, things becomes even more complicated, as you'll need to specify which app to use for each Heroku command.

And when deploying to production, wouldn't it be prudent to take a quick database snapshot first?

Time to automate this, I think...


Grab the deploy.sh script from the heroku-deploy-rails repo and commit it to your Rails app's git repository.

Then rename your Heroku remote to "production" (deploy.sh will only make backups of your database for remotes named "production" -- if you don't want to rename it, just edit the script).

$ git remote rename heroku production

You'll also want to configure the backup addon for your Postgres database:

$ heroku addons:add pgbackups:auto-month

Now you can take it for a spin.

$ ./deploy.sh
Usage: [BRANCH=master] deploy.sh <remote> [no-migrations]

        remote         Name of git remote for Heroku app
        no-migrations  Deploy without running migrations

You have to specify the name of the remote (list your remotes with git remote). The no-migrations switch is optional; deploy.sh will always put the app into maintenance mode and run migrations if you don't ask it not to.

That's about it. Almost. I added a git log command to show you which commits you're about to deploy...

$ ./deploy.sh production
From heroku.com:theagileplanner
   c1ded52..63985ee  master     -> production/master
Undeployed commits:

783e73d | 4 hours ago: Updated deploy.sh to latest heroku-deploy. (Graham Ashton)
8402bba | 81 minutes ago: Added cookieoi.eu JS to page. (Graham Ashton)

Press enter to continue...

Press Ctrl-C to abort deployment.


I love feedback and questions — please feel free to get in touch on Mastodon or Twitter, or leave a comment.