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!