📜 ⬆️ ⬇️

Dynamic subdomains using nginx + apache

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 Habré.

The problem is that this issue is covered everywhere 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 - you have earned a subdomain.

Sometimes, however, a solution to another problem is required - for example, the removal of the user profile and all the functionality associated with it to the subdomain.
For example, we have a ready-made site that has profiles on the following 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:

Nginx is above Apache on our site (as well as on many others), so I had to reinvent the wheel myself using this bundle (nginx + apache, since now, on almost all major sites, proxy nginx stands above Apache)

In general, the solution is simple - because The site has already been adjusted through mod_rewrite, the availability of links like www.example.com/users ([a-zA-Z _] +) 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 only to write a rule in the nginx config for rewriting subdomains. The rule turned out this decision is not correct, it is not recommended to use it :
location / { proxy_pass; 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 / { proxy_pass; } } server { server_name ~^(?<user>[a-z0-9\-]+)\.example.com$; location / { proxy_pass$user$uri$is_args$args; } } 

Thus, if a visitor came to the subdomain, then nginx determines this and requests from Apache already an address of the form www.example.com/users/username , and Apache already sort out everything further in accordance with its own mod_rewrite rules.

The resulting solution has the following advantages:


In general, the solution seemed to me to be quite good, ready to listen to recommendations and criticism from the gurus, because I myself am in setting up newer web servers, and perhaps the 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
For the server to handle dynamic subdomains correctly, you need to add one small entry 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

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

Source: https://habr.com/ru/post/101585/

All Articles