Dynamic subdomains using nginx + apache

  • Tutorial
This topic is another topic about the implementation of dynamic subdomains on the site, of which there are many on the Internet and there are even a couple of topics on the hub.

The problem is that this question is everywhere covered only from the point of view of redirection from a subdomain to a folder, and the whole dynamism of the subdomain is that you created a folder - the subdomain has worked for you.

Sometimes a solution to another problem is required - for example, taking a user profile and all the functionality that is associated with it to a subdomain.

For example, we have a ready-made site on which profiles work on this url: www.example.com/users/username , and there are all sorts of additional features (for example, www.example.com/users/username/contact and other pages related to this user).

And now we want to transfer everything related to the user to a subdomain, for example username.example.com , username.example.com/contact , etc.) The

solutions that were found on the Internet did not satisfy me for 2 reasons:
  • I did not find a solution how to make it work, while maintaining the domain www.example.com
  • All solutions found are suitable only for redirecting to a folder and do not work if any rules should work further

Our site has nginx above the apache (as well as on many others), so I had to reinvent the wheel myself using this bunch (nginx + apache, since now almost all large sites have proxy nginx above the apache)

In general, the solution is simple - because . Since the site has already been adjusted via mod_rewrite, the functionality of links of the form www.example.com/users ([a-zA-Z _] +) has already been established. It was decided to rewrite subdomains via nginx.

An additional condition is that our site works only as ww.example.com, and example.com redirects to www.

Accordingly, it remains just to write a rule in the nginx config for rewriting subdomains. The rule turned out to be this solution - it is not true, it is not recommended to use it :
                location / {
                        proxy_redirect http://www.example.com:8080/ /;
                        proxy_set_header Host $host;
                        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                        proxy_set_header X-Real-IP $remote_addr;
                        # учитываем что обязательно нужен www
                        set $uid "www";
                        # берем uid из поддомена
                        if ($host ~* "^(([a-z0-9\-]+)\.example\.com)$") {
                                set $uid $2;
                        # рерайтить нужно только если uid не www, на www работает весь сайт
                        if ($uid !~ "^(www)$") {
                                rewrite ^(.*)$ /users/$uid$1 break;

upd After the publication of the topic, BlackWizard suggested the best solution that meets all the initial conditions:
server {
    server_name   www.example.com;
    location / {
server {
    server_name   ~^(?[a-z0-9\-]+)\.example.com$;
    location / {

Thus, if a visitor visits the subdomain, then nginx determines this and asks for an address of the form www.example.com/users/username from the Apache , and the Apache further parses everything in accordance with its mod_rewrite rules.

The resulting solution has the following advantages:
  • No problem with www
  • It is easily implemented on any site with a ready-made link system (we will not consider the process of changing links on the site itself)
  • Works for both folders and url that use mod_rewrite

  • Proxy nginx required

In general, the solution seemed pretty good to me, I’m ready to listen to recommendations and criticism from the guru, because I myself am a beginner in setting up web servers, and maybe a solution will be useful to beginners like me.

UPD how to make username.example.com work without specifying all possible domains in the web server config.
In order for the server to correctly process dynamic subdomains, you need to add one small record to the DNS settings. This can be done using the server control panel.
Just add the following A format record (“A record” in the English version):
* .example.com

The record needs to be added after all subdomains (mail, smtp, etc.)

Also popular now: