Nginx redirect all old domain subdomains to new one

I had a very long domain, so I decided to change it to a shorter and more friendly one. But since I have a lot of subdomains (in fact, I have a subdomain wildcard), I wanted to keep the subdomain while changing only the domain part. So, I made the following rule:

server {
  listen 80;
  server_name ~^(\w+)\.olddomain\.com$;

  rewrite ^ $scheme://$1.doma.in$request_uri? permanent;
}

I have read a lot of other questions where this snippet solved the problem. But with me, Nginx always redirects to .domain.in, without any subdomains. What am I missing? I have tested the regex against regex101 and the examples work fine, Nginx seems unable to redirect it.


Solution 1:

Since nginx 0.8.25 named captures can be used in server_name. You should use them.

Here, the sub-domain will be stored in a variable called $sub. Then you will be able to reuse it in the rewrite directive :

server {
  listen 80;
  server_name ~^(?<sub>\w+)\.olddomain\.com$;
  rewrite ^ $scheme://$sub.doma.in$request_uri? permanent;
}

Alternatively, you can keep your actual Regex and use $1 in a return directive :

server {
  listen 80;
  server_name ~^(\w+)\.olddomain\.com$;
  return 301 $scheme://$1.doma.in$request_uri;
}

Finally, note that the return directive is the best approach for a redirect. You may run into Pitfalls using rewrite for a redirect.