Blog.

Implementing custom domains for Ruby on Rails applications

Cover Image for Implementing 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 The ultimate guide to custom domains for your SaaS app

The ultimate guide to custom domains for your SaaS app

Step-by-step guide to adding custom domains feature to any SaaS application

Drago Crnjac
Drago Crnjac
Cover Image for The Power of White-Labelling and Custom Domains for SaaS Businesses

The Power of White-Labelling and Custom Domains for SaaS Businesses

Empower your clients with white-labelling and custom domains. Let them seamlessly integrate your platform under their brand, enhancing trust and engagement. Dive into the technicalities with our guide or let SaaSCustomDomains.com simplify it for you.

Drago Crnjac
Drago Crnjac