Darren_Ter's avatar

Laravel Custom Domain : DNS, Nginx, and Routing

I am currently working for a CRM with domain name ( Exp: abc.com ). Each registered user will be assigned a subdomain ( Exp: 123.abc.com ), for them to design a landing page, and publish their landing page using that subdomain name.

The subdomain is worked well now. But now I want to step one level further, which each user can buy their own domain name ( Exp: apple.com ), and point their domain name to our server, and serve the exact same content as 123.abc.com.

After doing some research online, this is what I have now.

In my web.php :

Route::group(['domain' => '{customDomain}'], function () {
    Route::get('/',function($customDomain){
        return $customDomain;
    });
});

In my RouteServiceProvider :

To allow non-alphanumeric characters in custom domain :

public function boot()
{
    \Route::pattern('domain', '[a-z0-9.\-]+');
    parent::boot();
}

In my Nginx web server ( /etc/nginx/sites-available/abc.com ) :

To accept all incoming requests to my server :

server_name ~.;

That's all is what I done in Laravel.

In user's DNS provider ( Cloudflare ) :

I ask them to point their custom domain name to our website :

CNAME      apple.com       abc.com       DNS only 

Although all the things have been set up, but once the user type apple.com, it shows up this error :

enter image description here

Even the user have change the dns record to point to our server instead :

A      apple.com        123.123.123.123         DNS only

It does successfully show up our website, but my route for custom domain doesn't work. It show up the login page instead of return $customDomain.

Here I have a few questions :

  1. Do I need to ask the user to point to our website using CNAME record? But how to solve the cnamecross-user banned ?
  2. Is it correct to set my Nginx web server to accept all request like this : server_name ~.;
  3. Is there any errors on my custom domain route? I place it at the very top of route list.
  4. Is this feature consider a multi-tenancy system? We do ask a senior before, he said we need to almost rebuild our website for this feature, because it will change the infrastructure of our website. But we don't design to be each user will have their own database, all users will share a database.
  5. Do we need to do anything in cloudflare for such feature? Currently, we have the wildcard dns record ( A * 123.123.123.123 DNS only ) that accepts all requests already.
0 likes
5 replies
Darren_Ter's avatar
Darren_Ter
OP
Best Answer
Level 2

Okay, I solve it by myself already ^_^

  1. Since I am using Cloudflare free plan, to solve the cnamecross-user banned, I have to upgrade my plan to at least Pro plan ( $20 per month ).
  2. My Nginx work already. But it is not a good practice to accept all incoming requests, instead, I should have a whitelist of accepted requests, and a blacklist those suspicious domain names.
  3. Again, my route actually works. Just change the return to dd() and instead of $customDomain, display the custom domain using Request::getHost().
  4. Ya, this is considered multi-tenancy system. But since we are rush of time, we do a simple one, which each user will store their shared data in one database, rather than each user has their dedicated databases.
  5. Seems like after I have upgraded to Pro plan, I need to contact the customer supports for setup. I will update the answer here after this.
3 likes
Hypershapes's avatar

@nam_co You need to set a A record and set your server IP as target

A target 123.123.123.124 DNS only

And ask your user to point their domain to target.yourdomain.com

CNAME example target.yourdomain.com DNS only

For now, even though I didn't subscribed to paid cloudflare plan, but It still work.

Another note is, since we need to assign an SSL certificate to each of the custom domain that the user points to our server, so we have changed our web server from nginx to caddy. Caddy supports on demand SSL, which means it will automatically obtain a SSL certificate for a new domain that perform first TLS handshake with your server. Another cool thing is, Caddy will automatically handle the certificate renewal for you. You can read more here https://caddyserver.com/docs/automatic-https#on-demand-tls

HMDagher's avatar

@Hypershapes so as SAAS Owner i need to set an A record with server IP as target? or the SAAS subscriber should do this on his domain?

1 like
dondelion's avatar

Hi all! Im having a similar user case.

Isnt any way to simply get a CNAME status.external-domain.com to mask subdomain.myservice.com? Without reengineering Laravel routes?

Please or to participate in this conversation.