Score:0

Serve new subdomains dynamically

pl flag

I have a service example.com that needs to allow users to host a few files in their own subdomain userpage-userabc.example.com, similarly as does Github with userabc.github.io.

I currently use Apache, and each time I want to configure a new domain or subdomain, I have to create manually a new <VirtualHost>, restart the Apache server, etc. This is not possible here.

Example: if a visitor creates a new account userabc (added in a database), how to make that the userpage-userabc.example.com subdomain is available, and automatically serving files from /www/userabc/ or serving http://userpage-userabc.example.com/ with /www/main/index.php?user=userabc?

Note: *.example.com already has a wildcard A DNS-record to redirect to my server

What's a simple lightweight tool to do this "dynamic subdomain creation"? (I currently use Apache, PHP, Python, but I can use other tools).

Or is it possible with a single <VirtualHost> that catches all sudomains *.example.com and a RewriteRule including the subdomain?

Appleoddity avatar
ng flag
https://cwiki.apache.org/confluence/plugins/servlet/mobile?contentId=115522231#content/view/115522231
Appleoddity avatar
ng flag
https://httpd.apache.org/docs/2.4/vhosts/mass.html
Appleoddity avatar
ng flag
Seems to be several ways to accomplish this. I don’t think you’ve put much research or thought in to this.
pl flag
@Appleoddity Thanks for your comments. It's precisely because I have seen so many different methods and advice (such as "Use this plugin", "Move to nginx", "Use another server") that I miss the big picture of it, thus this question.
Appleoddity avatar
ng flag
This is where you decide what works best for you and implement it. Nobody can make this decision for you. We just don’t know enough about your use case or your technical expertise. The good news is there’s lots of ways to do this.
pl flag
@Appleoddity After further tests, I finally found what is probably the easiest solution with Apache + PHP and one single VirtualHost. Thanks for your help again!
Score:1
pl flag

As mentioned in a comment, here are references for Apache, there are multiple ways to do it: Dynamically Configured Mass Virtual Hosting, Dynamic mass virtual hosts with mod_rewrite.

The simplest solution I have found after a few more tests is: one single <VirtualHost>

<VirtualHost *:80>
  ServerName example.com
  ServerAlias *.example.com
  DocumentRoot /www/example
  <Directory />
    AllowOverride All
    Require all granted
  </Directory>
</VirtualHost>

with this wildcard ServerAlias.

With an .htaccess containing

RewriteEngine on
RewriteRule ^(.*)$ index.php [QSA,L]

we can then do all the routing for each user via PHP:

<?php
$host = $_SERVER['HTTP_HOST'];
$sname = $_SERVER['SERVER_NAME'];
// parse the subdomain of $host or $sname and deliver 
// the content accordingly (using the database)
?>

Benefit: it also works if the final user is using his own custom domain with a CNAME DNS record. Example:

www.userabc.com CNAME userpage-userabc.example.com

Then in the PHP, $host will here show www.userabc.com. If this custom domain information is somewhere in the database, we can serve the content accordingly, even if the user is using a custom domain.

Note: in the case for which users use their custom domain with CNAME, this is useful to determine which is the default VirtualHost to use when a request comes with a host which is not listed in the ServerName directives: Apache default VirtualHost.

Torin avatar
in flag
Just to add, you shouldn't add apex CNAME records like `userabc.com. CNAME userpage-userabc.example.com.`. DNS holds more than just `A/AAAA` and those will also be CNAME'd (see https://www.isc.org/blogs/cname-at-the-apex-of-a-zone/).
pl flag
Thanks @Torin, correct, I modified to `www.userabc.com. CNAME ...`. Btw, how do people that use a custom domain with "Github Pages" or with a similar hosting service that works with custom domain do? The [GH Pages doc](https://docs.github.com/en/pages/configuring-a-custom-domain-for-your-github-pages-site/managing-a-custom-domain-for-your-github-pages-site) says we should `www.johndoe.com. CNAME johndoe.github.io.`. But then how to do that `http://johndoe.com` serves the same content as `http://www.johndoe.com`? (if we cannot CNAME the `johndoe.com.`)
Torin avatar
in flag
Some DNS software have a virtual `CNAME`-like record (sometimes called `ALIAS` or `ANAME`) which will return `A/AAAA` records of that other name. If your DNS software/provider allows you to use those types of records, they'd be fine, but otherwise you'd need to manually add the `A/AAAA` records and update them when they change. The [GitHub docs](https://docs.github.com/en/pages/configuring-a-custom-domain-for-your-github-pages-site/managing-a-custom-domain-for-your-github-pages-site#configuring-an-apex-domain) do mention about the IPv4/6 records you'd need to add.
pl flag
Thanks @Torin! So in my example it should be `www.johndoe.com. CNAME johndoe.github.io.` and `johndoe.com. ALIAS johndoe.github.io.` or is the latter `johndoe.com. ALIAS www.johndoe.com.`?
pl flag
Last thing @Torin: if ALIAS/ANAME are not available by DNS provider, can we use DNAME (which seems available)?
Torin avatar
in flag
`DNAME` is like `CNAME` but for subnames, so it's also probably not what you want. If you're doing the GitHub pages, you'll probably want to add the four `A` records and the four `AAAA` records that are mentioned in the docs. It's a pain, but that's how it is :(
mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.