There are many ways to deploy a Ruby on Rails application to the internet. Between hosting on your own hardware, renting a virtual machine, using a cloud provider, and using a platform, the opportunities are endless. The low-hassle way to host a Rails application is to use a Platform as a Service (PaaS). In this article, we'll show you how to deploy a Rails Application to Render.com, and as a bonus, monitor it with Honeybadger! You can find the final project here on Github.
Going a step further than cloud hosting and using a platform to deploy your web apps provides incredible convenience at a cost. Under the hood, platforms such as Render and Heroku use Amazon Web Services or other cloud providers. Using a platform will cost you more than using a cloud provider directly, as the service is marked up. For the extra cost, you'll be able to deploy and scale a functional service without needing to understand or manage the underlying infrastructure. You'll also gain features like replication, autoscaling, and preview deployments without extra setup. Cloud providers are complicated enough to have built an ecosystem around education and certification, while platforms like Render allow developers to deploy an application in a single sitting.
Setting up an example Ruby on Rails application
If you're reading this, you likely already have a Rails app you'd like to deploy. In case you don't, we'll quickly go over creating a Rails app in this section.
If you don't already have rails installed, install version 7.1.1 with:
gem install rails -v 7.1.1
First, create a new Rails app using the rails new
command. We'll pass it a specific version:
rails _7.1.1_ new appname
Next, go into the directory that was created:
cd appname
Next, generate a new model and controller using the scaffold generator. For this example, we'll model "Event":
rails generate scaffold Event title:string date:datetime
This creates a number of files to support Creating, Reading, Updating, and Deleting Event
models in a database. We'll run the created database migration to create the necessary Events
table next with:
rails db:migrate
The scaffold already generated basic views, models, and controllers to support CRUD actions on events. To see the code in action, run the rails server with:
rails server
Now, visit localhost:3000/events
in your browser. You'll see a simple white page with an "Events" header and a "New event" button.
A screenshot of the Events Index Page
Clicking the button will take you to a form for creating the event, and creating the event will persist it in the database. You can also delete and edit an existing event, all from just the scaffold! This functional CRUD app will serve as a great example for our deployment. Push up the repository to Github as a final step.
Signing up for Render
Signing up for Render is easy. Signing up via Github will save you a step later, as we'll connect to Github to deploy our app. Render's free tier is generous, particularly for folks missing Heroku's free tier.
You can configure your service in the UI, or configure it in your codebase, using infrastructure as code. Many in the DevOps industry prefer infrastructure as code whenever possible, so we'll do that in this example.
Configuring your deployment with deploy.yaml
and build.sh
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
In this file, replace name_of_your_app
in all places with the name of your app. In our example, we'll call it event_tracker. This specifies that you want a web service and database on the free plan. You'll notice that the file references a build command in a file called bin/render-build.sh
, which doesn't exist yet. Create it, and paste the following:
#!/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 file will execute when your service starts, so they should go here if you need any other custom build steps.
Configuring Postgres as a database adapter
Rails applications begin using SQLite unless specified otherwise when generated. Render requires Postgres, so if your application doesn't yet have it, you'll need to add it.
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 update Gemfile.lock.
You must also change your database configuration in database.yml
to specify that Postgres should be used in production. Your database.yml
should now look 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: event_tracker_production
username: event_tracker
password: <%= ENV['EVENT_TRACKER_DATABASE_PASSWORD'] %>
You will need to swap out the value for the production database key, event_tracker_production
with the name of your app, appended by production
. You'll also need to make the username, event_tracker
, the name of your application. The environment variable for the production password should have the name of your app as APP_NAME_PASSWORD
. Render will automatically set that environment variable with the appropriate value.
Deploying with the Render dashboard
Once you have pushed all your app changes to GitHub, it's time to create your service in the Render dashboard. On the dashboard, select Blueprints, then "New Blueprint Instance." This will allow us to create a new service using our render.yml file.
Select the repository of the application you would like to deploy and give your blueprint a name. You'll also need to paste in your Rails Master Key, which you can get from the file in your repository (which is not checked into git) titled master.key
.
A screenshot of the Render dashboard
Paste in your master key, and let Render work its magic! In a few moments, your Rails application and its database will be live on the web. By default, Render will auto-deploy the service anytime a new commit is made to your default branch. Higher tiers of Render allow for more customization, like preview deployments.
Adding Honeybadger for monitoring
Honeybadger lets you quickly add application health monitoring to your app with minimal setup. After creating an account, add a new project in the dashboard.
A screenshot of the Honeybadger dashboard
After selecting your framework (Rails, in this case), you'll be met with some instructions for setting it up.
First, add the honeybadger gem by running:
bundle add honeybadger
Next, run the provided command to generate Honeybadger's configuration files and send a test alert.
Check in your changes and push them to GitHub, and Render will automatically deploy your application with Honeybadger!
To demonstrate the error monitoring, we can write a bug on purpose. For example, I can change my example application's events_controller.rb
to have an index method that references a class that I haven't yet written:
def index
@events = Birthday.all
end
Committing this and pushing it will auto-deploy the faulty code. After waiting a few minutes for the deploy, we can visit our application's URL and append /events
to visit the events index page that contains the bug. Bonus points if you can guess the Ruby error message!
Visiting the /events
route throws an error, which is promptly reported to Honeybadger. The error, stack trace, URL, and other helpful information are easily accessible in Honeybadger.
A screenshot of the Honeybadger error page
Conclusion
In conclusion, deploying a Ruby on Rails application using Render offers a straightforward and efficient solution for developers looking to streamline their deployment process. This guide has walked you through setting up a basic Rails app, configuring it for deployment on Render, and integrating Honeybadger for monitoring. The process, though involved, is simplified by the platform's user-friendly interface compared to cloud providers. As the web development landscape continues to evolve, tools like these help developers focus more on creating and less on the complexities of deployment and maintenance.