How to implement custom domains for Ruby on Rails applications
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.

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.

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).

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.