Headache free multiple accounts subdomains and private domains in web applications.

Our goal is to give our users the ability to use subdomains and private domains with zero hassle and with complete automation.

We have a web application that lets the user define a private subdomain like so:
account1.app-domain.com
account2.app-domain.com
account3.app-domain.com

app-domain.com is the main aplication domain.

To achieve this you do something like this:

Configure Wildcard Subdomains in your DNS zone file and in your web server virtual host.

Name Data Type
*.app-domain.com app-domain.com CNAME
app-domain.com 123.45.678.910 A

Apache virtual host:

ServerName *.ap-domain.com

In your application, find and load the account from the database via the subdomain field.

Rails routes file:

match '', to: homepage#show', constraints: lambda { |r| r.subdomain.present? && r.subdomain != 'www' }

So far so good

Next you want to allow the user to use his own private domain (with or without "WWW" prefix) like so:

WWW.USER1-PRIVATE-DOMAIN.COM

(with "WWW" prefix) will load

ACCOUNT1.APP-DOMAIN.COM

USER1-PRIVATE-DOMAIN.COM

(without "WWW" prefix) will load

ACCOUNT1.APP-DOMAIN.COM

WWW.USER2-PRIVATE-DOMAIN.COM

(with "WWW" prefix) will load

ACCOUNT2.APP-DOMAIN.COM

USER2-PRIVATE-DOMAIN.COM

(without "WWW" prefix) will load

ACCOUNT2.APP-DOMAIN.COM

and so on

To achieve this you do something like this:

On the server virtual host:

ServerName *.ap-domain.com

ServerAlias www.user1-private-domain.com

ServerAlias user1-private-domain.com

ServerAlias www.user2-private-domain.com

ServerAlias user2-private-domain.com

ServerAlias www.user3-private-domain.com

ServerAlias user3-private-domain.com

And so on

For each users private domain DNS zone:

Name Data Type
user1-private-domain.com 123.45.678.910 A
www user1-private-domain.com CNAME


Isn't it great?

Well not at all…

Problem

If you have 3 users then everything is fine, But what if you have 1000 users and you want everything to handle itself automatically?

Another problem

what if you decide to upgrade your server one day and you change the IP Address? Are you going to contact 1000 users to change their DNS zone file?

The solution is very simple and easy to achieve,You will not need to deal with settings at all, this functionality will be completely automatic.

Step 1:

Make your app the default site on the server so that a domain that is not listed in any of the virtual hosts on the server will end up pointing to the default site => Our application.

This will eliminate the need to update our virtual host with ServerAlias for every private domain. Whatever private domains coming our servers way will all point to our app.

Apache default site is the first configuration virtual host file in “sites-enabled” directory ordered by its name, so go to “sites-available” directory, disable (sudo a2dissite) the application, change the name of the conf file to 00000-myapp.conf and enable (sudo a2ensite) right back again. make sure the new name is the first when ordered by name. You will need to restart apache for the changes to take effect.

Step 2:

Initially instruct your users to configure their DNS zone like so:

Name Data Type
www app-domain.com CNAME

We point the subdomain to the application domain rather then to the private domain A record, Now you can change your servers IP Address Daily and all 1000 private domains (with www prefix) will always point to the right IP.

One more big headache elimination to go...

How do we make sure that the users private domain without www prefix will point to the right IP?

In the DNS zone we have an A record that points to the current app IP. But if we change the app IP someday all domains without www prefix will be lost.

Last step:

Buy a small 5$ VPS and install apache, Configure apache to redirect whatever domain (that does not have the www prefix) to the same domain but with the www prefix like so:
http://domain.com => 301 redirect to http://www.domain.com

Apache (default site) virtual host:

ServerAdmin erez@qcm.co.il
ServerName 133.22.666.444

RewriteEngine on
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteRule ^ http://www.%{HTTP_HOST}%{REQUEST_URI} [R=301,L,NE]

We use mod_rewrite to achieve this

RewriteEngine on
# The RewriteEngine directive enables the runtime rewriting engin
RewriteCond %{HTTP_HOST} !^www\. [NC]
# Check if the domain have www prefix in it? if yes proceed
RewriteRule ^ http://www.%{HTTP_HOST}%{REQUEST_URI} [R=301,L,NE]
# Redirect to the domain, Add “http://www.” in the beginning with status 301 moved permanently

Ones this server is up and running forever the user will set his DNS zone with an A record like so:

Name Data Type
user1-private-domain.com 133.22.666.444 A

Where 133.22.666.444 is the IP of the redirecting server.

Now when we go to a private domain like user1-private-domain.com without www prefix, we will always be redirected to www.user1-private-domain.com and to the right server IP and the right app on the server.

2 downsides:

  1. redirects will not work for https requests.
  2. the redirect will cost us time => the time it takes to redirect.

Well, nobody is perfect :)

Hope this helps somebody.

Discussion

To Joine the Discussion please authenticate: (10 sec | 2 clicks)
We will send you an email with a special link.