Best Practice:
The best practice, as well as the most efficient way, would be to use a separate server
definition for this.
This will not only ensure that the config is automatically applied to every single one of the websites that are hosted on your nginx instance, but it'll also makes sure that you don't end up running regular expressions on the hostname from multiple instances in your code.
The following is the simplest form:
server {
listen 80;
server_name ~^www\.(?<domain>.+)$;
return 301 $scheme://$domain$request_uri;
}
If you do use https
, then things get more complicated, because you'd have to ensure that the certificates don't mismatch. Unless you have a single certificate for all of your domains, it would be the best practice to simply hardcode everything, as it's already hardcoded in the certificate anyways, and a solution like above simply isn't possible due to the certificate requirements.
Alternative:
Note that the other answer to the question, which uses rewrite ^(.*) http://…$1 …
, is incorrect, and will cause you to lose $query_string
, as well as potentially mangle the encoding of the request as per Nginx pass_proxy subdirectory without url decoding.
If you require an if
-based approach and no hardcoding, neither of which are recommended, e.g., like the other answer, then at least use the correct paradigm, to avoid the bloat and the loss of the $query_string
; note that as per nginx server name regex when "Host" header has a trailing dot, the $host
variable is already normalised by nginx (trailing dot removed, whole thing brought to lower case), so, you don't need to worry about doing a case-insensitive comparison like in the other answer, either:
if ($host ~ ^www\.(?<domain>.+)$) {
return 301 $scheme://$domain$request_uri;
}
References: