How to Deploy a Rails App to Render

Jeff Morhous // March 05, 2023

Deploying a Rails app to the web isn't too complex of a task, depending on your approach. You can rent out an actual server, get a VPS, use a cloud provider like AWS or Azure, or use a PaaS. A PaaS, platform as a service, makes the process easier at the trade of expenses. Generally it's more expensive than other options, but it's certainly easier, especially if you're just trying to get some traction on a side project.

Render has risen in popularity in the last year, especially as Heroku eliminated their free tier. I've personally found Render to be the easiest way I've ever deployed a Rails app, and their free tier is pretty generous.

Start by signing up for Render. I found it easiest to just sign up with Github, given that I used a Github connection to trigger a deploy.

Changes to Your App

Render configuration

The configuration of Render can be done with Infrastructure as Code. Add a file to the root of your repository called render.yaml. In that file, paste this:

databases:
  - name: name_of_your_app
    databaseName: name_of_your_app
    user: name_of_your_app
    plan: free

services:
  - type: web
    plan: free
    name: name_of_your_app
    env: ruby
    buildCommand: "./bin/render-build.sh"
    startCommand: "bundle exec puma -C config/puma.rb"
    envVars:
      - key: DATABASE_URL
        fromDatabase:
          name: name_of_your_app
          property: connectionString
      - key: RAILS_MASTER_KEY
        sync: false

This tells Render that you want a web service and a database on the free plan.

Render build file

This configuration file references a build command, which points to a file that your application likely doesn't have yet. In your bin directory, add a file called render-build.sh. Paste following into that file:

#!/usr/bin/env bash
# exit on error
set -o errexit

bundle install
bundle exec rake assets:precompile
bundle exec rake assets:clean
bundle exec rake db:migrate

This is a series of commands that render will execute before starting a rails server, so if you need anything custom as part of your build process, this is the place to put it. If your app is an api-only app, you can delete the assets commands altogether.

Database configuration

Most rails applications begin using sqlite, at least in development. Render requires postgres, which is a rather easy change - you can even keep using sqlite in development.

In your Gemfile, add gem 'pg' to the main section of dependencies. Separately, move gem "sqlite3", "~> 1.4" into group: development.

Finally, run a bundle install to lock that change into your Gemfile.lock.

You also need to make changes to your database configuration to specify that postgres should be used in production. For me, this change looks like this:

default: &default
  adapter: postgresql
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
  timeout: 5000

development:
  <<: *default
  adapter: sqlite3
  database: db/development.sqlite3

# Warning: The database defined as "test" will be erased and
# re-generated from your development database when you run "rake".
# Do not set this db to the same as development or production.
test:
  <<: *default
  database: db/test.sqlite3

production:
  <<: *default
  database: name_of_your_app_production
  username: name_of_your_app
  password: <%= ENV['NAME_OF_YOUR_APP_DATABASE_PASSWORD'] %>

You can retain existing settings as long as they don't conflict with the postgresql adapter and database, username, and password. Be sure to use the same name_of_your_app as you used in the render.yaml

Application settings

In config/puma.rb, set the number of puma workers with the following line:

workers ENV.fetch("WEB_CONCURRENCY") { 4 }

Also in that same file, uncomment preload_app!

Lastly, in config/production.rb change the line that has config.public_file_server.enabled to be:

config.public_file_server.enabled = ENV['RAILS_SERVE_STATIC_FILES'].present? || ENV['RENDER'].present?

If you're using an Apple Silicon Mac, then you'll need to run:

bundle lock --add-platform x86_64-linux

Finally, commit all these changes and push them to Github.

Deployment Setup on the Render dashboard

In the Render Dashboard, click "Blueprints", then "New Blueprint Instance".

Connect to the repository you wish to deploy. Enter any environment variables you might need, like the Rails Master Key. When you click next, your application and database should deploy!


If you enjoyed this, consider signing up to my newsletter to get occasional updates about new things I make or write.