Blog.

How to implement custom domains for Ruby on Rails applications

Cover Image for How to implement custom domains for Ruby on Rails applications
Drago Crnjac
Drago Crnjac

In this guide, we'll show you how to use the SaaS Custom Domains API to implement custom domains in your Ruby on Rails application.

You can also do it manually through the SaaS Custom Domains UI with a few mouse clicks.

But, I'd recommend using the API to automate the entire process. Especially if you need to add a lot of custom domains or plan to let your customers add custom domains without waiting for you to click around our UI.

The entire process should take between 5 and 20 minutes, depending on if you want to do step 5 which is optional.

Steps

1. Create an API token (1 minute)

2. Create an upstream (1 minute)

3. Create a custom domain (1 minute)

4. Create CNAME for the custom domain (1 minute)

5. Handle forwarded requests in the Rails application (optional, 5-15 minutes)

Create an API token

First, you need to do get your API token from the account settings.

Screenshot showing the API tokens settings in the UI.

Once you have the API token, you are ready to make API calls to SaaS Custom Domains API.

Create an upstream

An upstream refers to the server that the reverse proxy forwards requests to. In your case, this is the Rails application server where you expect to receive requests.

First, get your account UUID from the settings.

Screenshot of the account settings page in the UI

Let's assume your app is hosted at app.example.com, spin up the Rails console and create the upstream like this:

require 'net/http'
require 'uri'
require 'json'

account_uuid = 'your_account_uuid'
token = 'your_api_token'

base_url = "https://app.saascustomdomains.com/api/v1" 
url = URI("#{base_url}/accounts/#{account_uuid}/upstreams")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

data = { host: 'app.example.com' }

request = Net::HTTP::Post.new(url)
request['Authorization'] = "Bearer #{token}"
request['Content-Type'] = 'application/json'
request.body = JSON.dump(data)

response = http.request(request)

JSON.parse(response.read_body)
=>
{"uuid"=>"your_upstream_uuid",
 "host"=>"app.example.com",
 "port"=>443,
 "tls"=>true,
 "bubble_io"=>false,
 "created_at"=>"2023-03-14T15:47:56.844+01:00",
 "updated_at"=>"2023-03-14T15:47:56.844+01:00",
 "account_uuid"=>"your_account_uuid"}

Congrats! You successfully created your first upstream. To learn more about upstreams and all the things you can do with them check out our Upstreams API Documentation.

Create a custom domain

Now that we have our upstream, let's create a custom domain that will forward requests to it. As an example, we'll imagine a customer wants to add app.mydomain.com as a custom domain.

require 'uri'
require 'net/http'

account_uuid = 'your_account_uuid'
upstream_uuid = 'your_upstream_uuid'
token = 'your_api_token'

custom_domain_host = 'app.mydomain.com'
base_url = "https://app.saascustomdomains.com/api/v1"
url = URI("#{base_url}/accounts/#{account_uuid}/upstreams/#{upstream_uuid}/custom_domains")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Post.new(url)
request['Authorization'] = "Bearer #{token}"
request['Content-Type'] = 'application/json'
request.body = {
  host: custom_domain_host
}.to_json

response = http.request(request)

JSON.parse(response.read_body)
=>
{"uuid"=>"your_domain_uuid",
 "host"=>"app.mydomain.com",
 "created_at"=>"2023-03-14T16:04:05.489+01:00",
 "updated_at"=>"2023-03-14T16:04:05.489+01:00",
 "last_dns_check_at"=>nil,
 "status"=>"pending_check",
 "instructions_recipient"=>nil,
 "instructions_email_sent_at"=>nil,
 "upstream_uuid"=>"your_upstream_uuid"}

Congrats! You created your first custom domain. To learn more about custom domains and everything you can do with them check out our Custom Domains API Documentation.

Create CNAME for the custom domain

The custom domain has now been created in our system, but if you visit it, nothing happens. Why?

In order for the custom domain to work, you need to create a CNAME on app.myapp.com and point it to in.saascustomdomains.com. In practice, you would tell your customer to create the CNAME record on their domain.

After you create the CNAME record, it may take a few minutes for the DNS changes to propagate. Once the DNS changes have been propagated, when you visit the custom domain app.myapp.com, your request will be forwarded to your upstream host — app.example.com — where your Rails application lives.

Note: If your customers are using a DNS provider like CloudFlare, that can also act as a proxy, make sure they set the proxy status to DNS only (make the little cloud icon gray).

DNS records should have the DNS Only option enabled.

Congratulations! The requests are being forwarded all the way from your custom domain to your Rails application.

Depending on your use case and how your Rails application is implemented, this may be exactly what you wanted and there's nothing else you need to do.

But, you may want to implement some business logic depending on the custom domain from which the request is originating from. If that's the case, read on.

Handle forwarded requests in the Rails application

Maybe you want to show a different logo on your page or pull different data from your database depending on the custom domain. Here is how you can do that.

Every request coming from a custom domain will have the X-Served-For set to that custom domain. For example, if the request is coming from app.myapp.com, the X-Served-For will be set to app.myapp.com.

Here's how you can handle it in a Rails controller:

class MyController < ApplicationController
  def index
    if request.headers['X-Served-For'] == 'app.myapp.com'
      # Do something for app.myapp.com
    elsif request.headers['X-Served-For'] == 'app.other-customer.com'
      # Do something for app.other-customer.com
    else
      # Default logic for all other users
    end
  end
end

That is it!

We implemented custom in 5 easy steps using the SaaS Custom Domains API. If you have any questions please reach out to us via email or via chat widget at saascustomdomains.com.


More Stories

Cover Image for Step-by-Step Guide: Implementing Custom Domains in Your Django SaaS App

Step-by-Step Guide: Implementing Custom Domains in Your Django SaaS App

Discover how to easily integrate custom domains in your Django SaaS app with SaaS Custom Domain API. Enhance user experience & branding today!

Drago Crnjac
Drago Crnjac
Cover Image for Step-by-Step Guide - Implement Custom Domains in Your Node.js SaaS App

Step-by-Step Guide - Implement Custom Domains in Your Node.js SaaS App

Complete guide to implementing custom domains for your SaaS application in Node.js

Drago Crnjac
Drago Crnjac