DEPLOYING RAILS-ONLY API WITH RENDER

Michael Munavu
6 min readDec 11, 2022

--

With Heroku's free tier ended, developers have been looking for alternatives to deploy their rails backend apps.

Credits to David Vera Castillo

Well, worry no more

Set your repository with PostgreSQL

Ruby on Rails comes with SQLite3 configured by default so you need to install PostgreSQL in your application.

If you are creating a new project from scratch you should use:

rails new myfirstsite --database=postgresql

If you are deploying an existing repository you need to ensure that in your Gemfile the line:

gem 'sqlite3'

to

gem 'pg'

Then, to install the dependencies you need to run:

bundle install

You should push your changes into GitHub because Render allows you to deploy whenever the configured branch is pushed.

Finally, you need to check the config/database.yml file contains the postgresql adapter in the default section, as follows:

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 } %>

And in the production section, usually at the end of the file, you need to replace the default values with these :

production:
<<: *default
url: <%= ENV['DATABASE_URL'] %>

Modify the project configurations

Open config/puma.rb and change it to the following code below.

# Puma can serve each request in a thread from an internal thread pool.
# The `threads` method setting takes two numbers: a minimum and maximum.
# Any libraries that use thread pools should be configured to match
# the maximum value specified for Puma. Default is set to 5 threads for minimum
# and maximum; this matches the default thread size of Active Record.
#
max_threads_count = ENV.fetch("RAILS_MAX_THREADS") { 5 }
min_threads_count = ENV.fetch("RAILS_MIN_THREADS") { max_threads_count }
threads min_threads_count, max_threads_count

# Specifies the `port` that Puma will listen on to receive requests; default is 3000.
#
port ENV.fetch("PORT") { 3000 }

# Specifies the `environment` that Puma will run in.
#
environment ENV.fetch("RAILS_ENV") { "development" }

# Specifies the `pidfile` that Puma will use.
pidfile ENV.fetch("PIDFILE") { "tmp/pids/server.pid" }

# Specifies the number of `workers` to boot in clustered mode.
# Workers are forked web server processes. If using threads and workers together
# the concurrency of the application would be max `threads` * `workers`.
# Workers do not work on JRuby or Windows (both of which do not support
# processes).
#
workers ENV.fetch("WEB_CONCURRENCY") { 4 }

# Use the `preload_app!` method when specifying a `workers` number.
# This directive tells Puma to first boot the application and load code
# before forking the application. This takes advantage of Copy On Write
# process behavior so workers use less memory.
#
preload_app!

# Allow puma to be restarted by `rails restart` command.
plugin :tmp_restart

Open open/environments/production.rb and find the following line:

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

And replace it with this line ..

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

ENABLE RACK CORS

The CORS spec allows web applications to make cross-domain AJAX calls without using workarounds such as JSONP. See Cross-domain Ajax with Cross-Origin Resource Sharing

Add this to your gemfile:

gem 'rack-cors'

run


bundle install

in your config/initializers folder add a cors.rb file if you do not have one and have this code inside that file

Rails.application.config.middleware.insert_before 0, Rack::Cors do
allow do
origins "*"

resource "*",
headers: :any,
methods: [:get, :post, :put, :patch, :delete, :options, :head]
end
end

Create a PostgreSQL database

Render allows users to create one PostgreSQL database that lasts 90 days in the free tier. You can always create a new one when the old one expires. The process of creating one goes as follows:

  1. Login to render.com or create a new account if you haven’t already. You can use your GitHub account to allow your repositories to be deployed on push.
  2. In the navbar click on the New button and select the PostgreSQL option:
  3. Choose a name and a region. You can also customize the database name, user, and version if you need it , but these are not necessary .
  4. Choose the Free Plan Type and click on Create Database
  5. Wait until the newly created database is deployed, then copy its Internal Database URL and save it for later.

Create a build script

Now, we need to create a build script. This script differs when deploying an API-Only application from the instructions found in Render Docs, and that can cause a lot of headaches. For API-Only applications, you need to create a file called render-build.sh in the bin folder and paste the following:

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

bundle install
bundle exec rake db:migrate

If you want to load seed values for your database you should append the following line at the end of the file:

bundle exec rake db:seed

Next, make sure the script is executable by running the following command in the console:

chmod a+x bin/render-build.sh

Then, push the changes and you are ready to deploy.

Create a Web Service

Now you can create a Web Service in Render by clicking on New >> Web Service.

In the next window, configure your GitHub account if you haven’t. Then, you can choose the repository you want to deploy. Find it and click on Connect.

Afterward, you can configure a unique name, the region, and the branch you want to deploy, in case you don’t want to deploy the default GitHub branch.

IMPORTANT !!!

Ensure that the environment is set to Ruby. Make sure to clear the Build Command and set it to:

./bin/render-build.sh

Which calls the previously created script. Also, clear the Start Command and set it to:

bundle exec puma -C config/puma.rb

You should have your configuration as follows:

Next, you can check the Plan Type and ensure is set to Free. Then, you should click the Advanced button.

Now you need to add all the environmental variables your application requires. The two mandatory variables are:

DATABASE_URL => The internal database URL that you saved above form you PostgreSQL service
RAILS_MASTER_KEY => Paste contents of the config/master.key file

Finally, you can click Create Web Service, and you can check the progress of the deployment. I recommend that you check the logs to ensure everything worked correctly. If you followed these steps your application should deploy successfully.

Now if you go to your web service and add a route at the end you will see your data .

https://renderfrontend-b3zp.onrender.com/plants

You now see this

I hope you found this article useful. I realize that this article may not cover all the Rails implementations you may use, but it can certainly guide you when facing this challenge. I have tested this process with several of my repositories successfully but it’s always good to be careful. Happy coding!

--

--