Deploy a Ruby on Rails app with Render.com
With the end of Heroku’s free tier hosting services a lot of people are looking for alternatives. I have found Render to be a great service for hosting individual and side projects, especially with Rails. In this article I’ll go through how to set up your app for deployment with Render from start to finish.
First things first though, make sure you sign up for an account with Render here. You will also need to enter valid credit card details, but don’t worry you won’t get charged. So let’s start!
1. First you want to make a new rails app:
rails new my-app-render --database=postgresql
We are using a PostgreSQL database because that is the default type that Render uses.
2. Create your database with rails db:create
and then run rails s
just to check that your app is running locally with no issues.
Now even though we have no content in our app we have the skeleton, so this is the best time to set up deployment, as it will allow for as few potential errors as possible.
3. Check your Gemfile to make sure that the gem 'pg'
is there. It should be as we created our app with this database specified. If you are deploying an already existing app however, or just didn’t specify the database, make sure that the gem 'pg'
is here instead of the default gem 'sqlite3'
Then run bundle install
in your terminal.
4. Next navigate to your config/database.yml
file and update it to use the PostgreSQL adapter, see below
default: &default
adapter: postgresql
encoding: unicode
# For details on connection pooling, see Rails configuration guide
# https://guides.rubyonrails.org/configuring.html#database-pooling
pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
Still in config/database.yml
we then want to update our production variables to the following. It’s default location is at the very bottom of the file.
production:
<<: *default
url: <%= ENV['DATABASE_URL'] %>
#
# Read https://guides.rubyonrails.org/configuring.html#configuring-a-database
# for a full overview on how database connection configuration can be specified.
#
production:
<<: *default
url: <%= ENV['DATABASE_URL'] %>
database: my_app_render_production
username: my_app_render
password: <%= ENV['MY_APP_RENDER_DATABASE_PASSWORD'] %>
5. Once this is done, open your config/puma.rb
and make some small changes. Find the commented line that says
#workers ENV.fetch("WEB_CONCURRENCY") {2}
Uncomment it and change it to workers ENV.fetch("WEB_CONCURRENCY") {4}
This will give us 4 workers to boot when in clustered mode.
Still in the config/puma.rb
file, find the commented line #preload_app!
and uncomment it. If you want to know more about what exactly this is doing see Puma’s GitHub read-me on the preload method here.
6. Open the config/environments/production.rb
file and change this:
# Disable serving static files from the `/public` folder by default since
# Apache or NGINX already handles this.
config.public_file_server.enabled = ENV['RAILS_SERVE_STATIC_FILES'].present?
to this:
# Disable serving static files from the `/public` folder by default since
# Apache or NGINX already handles this.
config.public_file_server.enabled = ENV['RAILS_SERVE_STATIC_FILES'].present? || ENV['RENDER'].present?
7. Next we need to create a build script in the root of our repository. These commands will run every time we deploy to render. Double check the root repository location by running git rev-parse --show-toplevel
in your terminal. The printed directory is your root repository. Navigate to this location and run touch render-build.sh
this creates the file where we will write our render build script.
Open the file in your text editor and paste the following into the file.
# exit on error
set -o errexit
bundle install
bundle exec rails assets:precompile
bundle exec rails assets:clean
bundle exec rails db:migrate
#if you have seeds to run add:
# bundle exec rails db:seed
After saving the file we now need to make sure that it is executable. Navigate to your root repository in your terminal and run chmod a+x render-build.sh
If no messages pop up then all is well.
8. Next create a render.yaml
file in your root repository with touch render.yaml
This file includes information about your Rails Web Service and the database that is used by your app. Input the following changing the databaseName
, user
, and services: name
key variables to the name of your app if it differs.
databases:
- name: postgres
ipAllowList: []
databaseName: my_app_render
user: my_app_render
services:
- type: web
name: my_app_render
env: ruby
buildCommand: "./render-build.sh"
startCommand: "bundle exec rails s"
envVars:
- key: DATABASE_URL
fromDatabase:
name: postgres
property: connectionString
- key: RAILS_MASTER_KEY
sync: false
Make sure all your files are saved and commit and push your changes to your repository on GitHub.
9.Now head over to the Render website. On the Render Dashboard navigate to Blueprints and click on ‘New Blueprint Instance’
If you haven’t connected your GitHub account to Render already, this is the time, click here to do so. Then click Connect on your chosen repository.
Here enter your unique service group name: (your app name is fine)
After that in the deploy window below, set the value of the RAILS_MASTER_KEY
to the contents of your config/master.key
file. Then click Apply
Go the the Dashboard tab to see the progress it should say deploying…
After it finishes your Rails app should be live! Make sure that your instance type is the free one by navigating to Dashboard - Settings and making sure your instance type is set to Free
Your render URL will always be https://my-app-render.onrender.com with the my-app-render replaced by whatever you have called your app.
At the moment when you visit your URL nothing will show up, as per this tutorial, we didn’t code any contents for our app. From this point out however, every time you push to the master branch on Github your changes will auto deploy with Render, cool right! Go add some contents and check it out.
Hope this was helpful and have fun with Rails and Render!