Home > Software engineering >  nginx Redirect specific subdomain and path
nginx Redirect specific subdomain and path

Time:12-07

Our nginx config serves multiple sites with their own subdomains.

server {
  listen 80 default_server;
  listen [::]:80 default_server;

  server_name ~^(?P<sub>. )\.(example1|example2)\.com$;
  root /var/www/instances/$sub;

  ...
}

I want to redirect one specific subdomain with its path to different sites, but I cannot figure out how to write the check. I need to check for the host part and then check for the path to decide where the redirect should land.

The map looks somehting like this:

Old URI New URI
sub1.example1.com/wiki/0/$path newSub1.example1.com/wiki/0/$path
sub1.example1.com/wiki/20/$path newSub2.example1.com/wiki/0/$path

Where $path is simply the rest of the request URI

All other requests to sub1.example1.com should work as before.

CodePudding user response:

The obvious solution is to split sub1.example1.com into a separate server block. As you will see from this document a server_name with an exact name always takes precedence over a server_name with a regular expression.

This means that their are two server blocks with near identical contents, but this can be mitigated by using the include directive.


Alternatively, you can test the value of $host$request_uri using a map directive. This is less efficient, as you will be testing the URL in every site.

For example:

map $host$request_uri $redirect {
    default 0;
    ~*^sub1.example1.com/wiki/0/(?<path>.*)$ //newSub1.example1.com/wiki/0/$path;
    ~*^sub1.example1.com/wiki/20/(?<path>.*)$ //newSub2.example1.com/wiki/0/$path;
}

server {
    listen 80 default_server;
    listen [::]:80 default_server;

    server_name ~^(?P<sub>. )\.(example1|example2)\.com$;
    root /var/www/instances/$sub;
    if ($redirect) { return 301 $scheme:$redirect; }

    ...
}
  • Related