Heroku Deployments
I’ve been doing a rewrite of Lettra in Rails 8 and taking note of the deployment process to Heroku1.
Start App and Create Database
$ rails new lettra --database=postgresql
$ bin/rails db:create
Create Welcome Page
$ rails g controller welcome
Create app/views/welcome/index.html.erb
and add a “Hello, World” message:
<h1>Hello, World!</h1>
<p>The time is now: <time><%= Time.now %></time></p>
I’m using Time.now
as a bit of a sanity check because Heroku won’t be using our local PST timezone by default.
To make this page the root page for the app, we update the config/routes.rb
file with:
root "welcome#index"
At this point we should be able to see the app on port 3000 by running rails s
in the CLI.
Specify Ruby Version
I’m currently on Ruby 3.3.4. Newest version as of time of writing is 3.3.7, but no need to be on the cutting edge just yet since Rails 8 was released in mid-December and it supports anything past version 3.3.
So we add the desired Ruby version in the Gemfile and run $ bundle update --ruby
. We can then verify the change was successful by running $ cat Gemfile.lock | grep RUBY -a1
Create Procfile
The Procfile explicitly declares what command to execute to start the app. I’m using the Puma web server since it’s fast, tested, and has support for Rack middleware.
In the root directory we create the Procfile and add this to the file:
web: bundle exec puma -C config/puma.rb
Git
Add all and commit changes to repo.
Create a Heroku App
From CLI in app’s root directory:
$ heroku apps:create
This creates a $7/mo “web” Dyno.
Provision Heroku Database
Note from Heroku:
A mini Postgres size costs $5 a month, prorated to the minute.
$ heroku addons:create heroku-postgresql:essential-0
Environment Variables
Update: While this wasn’t an issue for the inital deployment, Heroku throws an error when attempting to run subsequent migrations on the production database with the default Rails configuration.
Heroku will throw the following error: ActiveRecord::ConnectionNotEstablished error when running rails db:migrate on Heroku
.
It’ll look something like this:
ActiveRecord::ConnectionNotEstablished: connection to server on socket "/var/run/postgresql/.s.PGSQL.5432" failed
It’s an easy fix though, we can provide access to the Heroku database ENV variable by updating the config/database.yml
.
production:
primary: &primary_production
<<: *default
url: <%= ENV['DATABASE_URL'] %>
cache:
<<: *primary_production
database: lettra_production_cache
migrations_paths: db/cache_migrate
queue:
<<: *primary_production
database: lettra_production_queue
migrations_paths: db/queue_migrate
cable:
<<: *primary_production
database: lettra_production_cable
migrations_paths: db/cable_migrate
That’s all!
Deploy to Heroku
$ git push heroku main
After a successful deployment, complete these tasks as necessary:
- Database migrations
- Scale dynos (not needed yet)
- Check app’s logs if issues arise
Migrate Heroku Database
$ heroku run rake db:migrate
Fix Timezone to PST from GMT
$ heroku config add: TZ="America/Los_Angeles"
Open App in Browser
$ heroku open
View App Logs
$ heroku logs
By appending the -t
/ --tail
flag, we can see a full, live stream of the app’s logs:
$ heroku logs --tail
At this point, the starting cost for a Rails app with a Heroku backend will be max around $12.00 / month. The provision for the database is always the most expensive part of it, since not using the app does bring the cost down on the web dyno front.
-
Since deploying to production will be the main focus of this devlog, I’m referencing this article from the Heroku Dev Center. ↩