How can I support dynamic custom subdomains (CNAMEs) pointing to my Railway app?
manojnaidu619
PROOP

4 months ago

I’m building a multi-tenant SaaS app, and I need help figuring out how to handle dynamic custom subdomains.

Here’s the situation:

  • My main web app is hosted on a custom domain connected to Railway, for example:

    app.myapp.com
    
  • I’d like my users to be able to connect their own subdomains to it, like:

    dashboard.customer.com → CNAME → app.myapp.com
    
  • When someone visits dashboard.customer.com, I want Railway to serve the same app (my backend detects the tenant based on the Host header).

Right now, if I try this, I get the “Train has not arrived at the station” message — which I understand means Railway doesn’t recognize the domain until it’s manually added under Settings → Networking → Custom Domains.

That works for testing, but in production this won’t scale. I need a setup where customers can connect their own subdomains automatically (like other SaaS platforms that use wildcard or dynamic domain mapping).

So my questions are:

  1. Does Railway support dynamic custom domains - so any CNAME pointing to my base domain is accepted automatically?

  2. If not, is there an API or programmatic way to register new custom domains from my app when a customer adds theirs?

I’m basically trying to let customers point subdomain.theirdomain.comapp.myapp.com and have it just work, without manually adding every new domain inside Railway.

Thanks so much for any clarification or suggestions! pray emoji

$30 Bounty

4 Replies

Railway
BOT

4 months ago

Hey there! We've found the following might help you get unblocked faster:

If you find the answer from one of these, please let us know by solving the thread!


manojnaidu619
PROOP

3 months ago

Any update on this please? I'm stuck.


callmeal3x
PRO

3 months ago

Hey! I found out your question was interesting, so here is my answer :

Option 1: Wildcard Subdomains (What I Use)

Just add *.myapp.com in Railway → Settings → Custom Domains

DNS Setup:

*.myapp.com  →  CNAME  →  <your-railway-domain>.up.railway.app
*.myapp.com  →  CNAME  →  authorize.railwaydns.net

Important: If you're using Cloudflare, make sure authorize.railwaydns.net is DNS-only (gray cloud, not proxied).

In my app:

const host = req.headers.host; // "customer1.myapp.com"
const tenant = host.split('.')[0]; // "customer1"

That's it! Now customer1.myapp.com, customer2.myapp.com, etc. all work without touching Railway again.

Option 2: True Custom Domains (Their Own Domain)

If customers want dashboard.customer.com pointing to your app, you'll need to use Railway's API:

const addCustomDomain = async (domain) => {
  await fetch('https://backboard.railway.app/graphql/v2', {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${process.env.RAILWAY_API_TOKEN}`,
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      query: `mutation customDomainCreate($input: CustomDomainCreateInput!) {
        customDomainCreate(input: $input) { id domain status }
      }`,
      variables: {
        input: {
          domain,
          serviceId: process.env.RAILWAY_SERVICE_ID,
          environmentId: process.env.RAILWAY_ENVIRONMENT_ID
        }
      }
    })
  });
};

The flow: customer enters their domain → my backend calls Railway API → customer adds the CNAME → Railway handles SSL automatically.

My recommendation: Start with wildcards. It's zero maintenance and scales perfectly. Only add the API integration if customers really need their own branded domains.

Check out the docs here: https://docs.railway.com/guides/public-networking#wildcard-domains

Hope this helps! pray emoji


callmeal3x

Hey! I found out your question was interesting, so here is my answer :Option 1: Wildcard Subdomains (What I Use)Just add *.myapp.com in Railway → Settings → Custom DomainsDNS Setup:*.myapp.com → CNAME → <your-railway-domain>.up.railway.app *.myapp.com → CNAME → authorize.railwaydns.netImportant: If you're using Cloudflare, make sure authorize.railwaydns.net is DNS-only (gray cloud, not proxied).In my app:const host = req.headers.host; // "customer1.myapp.com" const tenant = host.split('.')[0]; // "customer1"That's it! Now customer1.myapp.com, customer2.myapp.com, etc. all work without touching Railway again.Option 2: True Custom Domains (Their Own Domain)If customers want dashboard.customer.com pointing to your app, you'll need to use Railway's API:const addCustomDomain = async (domain) => { await fetch('https://backboard.railway.app/graphql/v2', { method: 'POST', headers: { 'Authorization': `Bearer ${process.env.RAILWAY_API_TOKEN}`, 'Content-Type': 'application/json', }, body: JSON.stringify({ query: `mutation customDomainCreate($input: CustomDomainCreateInput!) { customDomainCreate(input: $input) { id domain status } }`, variables: { input: { domain, serviceId: process.env.RAILWAY_SERVICE_ID, environmentId: process.env.RAILWAY_ENVIRONMENT_ID } } }) }); };The flow: customer enters their domain → my backend calls Railway API → customer adds the CNAME → Railway handles SSL automatically.My recommendation: Start with wildcards. It's zero maintenance and scales perfectly. Only add the API integration if customers really need their own branded domains.Check out the docs here: https://docs.railway.com/guides/public-networking#wildcard-domainsHope this helps!

manojnaidu619
PROOP

2 months ago

hey, thanks for the detailed response. But how many entries can I add through railway API? I'm sure there's a very small limit.


Loading...