Rails on Heroku

The official guide is a great place to start, but there’s more you can do to make life easier.

🍊 Based on lessons learned in the early days of Instacart

Deploys

For zero downtime deploys, enable preboot. This will cause deploys to take a few minutes longer to go live, but it’s better than impacting your users.

heroku features:enable -a appname preboot

Add a preload check make sure your app boots. Create lib/tasks/preload.rake with:

task preload: :environment do
  Rails.application.eager_load!
  ::Rails::Engine.subclasses.map(&:instance).each { |engine| engine.eager_load! }
  ActiveRecord::Base.descendants
end

And add a release phase task to your Procfile to run the preload script and (optionally) migrations.

release: bundle exec rails preload db:migrate

Create a deployment script in bin/deploy. Here’s an example:

#!/usr/bin/env bash

function notify() {
  # add your chat service
  echo $1
}

notify "Deploying"

git checkout master -q && git pull origin master -q && \
git push origin master -q && git push heroku master

if [ $? -eq 0 ]; then
  notify "Deploy complete"
else
  notify "Deploy failed"
fi

Be sure to chmod +x bin/deploy. Replace the echo command with a call to your chat service (Hipchat instructions).

Deploy with:

bin/deploy

Migrations

Follow best practices for zero downtime migrations.

If you start to see errors about prepared statements after running migrations, disable them.

production:
  prepared_statements: false

Don’t worry! Your app will still be fast (and you’ll probably do this anyways at scale since PgBouncer requires it).

Rollbacks

Create a rollback script in bin/rollback.

#!/usr/bin/env bash

function notify() {
  # add your chat service
  echo $1
}

notify "Rolling back"

heroku rollback

if [ $? -eq 0 ]; then
  notify "Rollback complete"
else
  notify "Rollback failed"
fi

Don’t forget to chmod +x bin/rollback. Rollback with:

bin/rollback

Logs

Add Papertrail to make your logs easily searchable.

heroku addons:create papertrail

Set it up to archive logs to S3.

Performance

Add a performance monitoring service like New Relic.

heroku addons:create newrelic

And follow the installation instructions.

Use a CDN like Amazon CloudFront to serve assets.

Autoscaling

Check out HireFire.

Productivity

Use Archer to enable console history.

Use aliases for less typing.

alias hc="heroku run rails console"

Staging

Create a separate app for staging.

heroku create staging-appname -r staging
heroku config:set RAILS_ENV=staging RACK_ENV=staging -r staging

Deploy with:

git push staging branch:master

You may also want to password protect your staging environment.

class ApplicationController < ActionController::Base
  http_basic_authenticate_with name: "happy", password: "carrots" if Rails.env.staging?
end

Lastly...

Have suggestions? Please share. For more tips, check out Production Rails.

🐥 Happy coding!

Published August 12, 2015


You might also enjoy

New Rails App Checklist

PgBouncer Setup

Bulk Upsert in Ruby/Rails


All code examples are public domain.
Use them however you’d like (licensed under CC0).