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!