Photo by Sajad Nori on Unsplash
How to remove "www" and redirect to "http" to "https" on Nginx webserver
The best way to accomplish this is using three server blocks as follow:
The reason for using extra server blocks instead of "if" directive is that server selection is performed using a hash table, and is very fast. Using a server-level "if" directive means, its run for every request, which is wasteful. Also, capturing the requested uri in the rewrite is wasteful, as Nginx already has this information in the $uri and $request_uri variables (without and with query string, respectively).
# Redirect default http to https
server {
listen 80;
server_name yourdomain.com www.yourdomain.com;
return 301 https://yourdomain.com$request_uri;
}
# Redirect https://www to https://
server {
listen 443 ssl;
ssl_certificate /path/to/server.cert;
ssl_certificate_key /path/to/server.key;
server_name www.yourdomain.com;
return 301 https://example.com$request_uri;
}
# Actual handling https requests (without www - default) eg., https://yourdomain.com
server {
listen 443 ssl;
ssl_certificate /path/to/server.cert;
ssl_certificate_key /path/to/server.key;
server_name yourdomain.com;
(add the rest of processing requests)
}
If you want to include www, you will only need two server blocks for port 80 and port 443 SSL as follow:
# http to https
server {
listen 80;
server_name yourdomain.com www.yourdomain.com;
return 301 https://www.yourdomain.com$request_uri;
}
# Actual handling https requests (with www - default) eg., https://www.yourdomain.com
server {
listen 443 ssl;
server_name yourdomain.com www.yourdomain.com;
# SSL managed by Certbot
ssl_certificate /etc/letsencrypt/live/yourdomain.com/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/yourdomain.com/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
# Redirect non-https traffic to https
if ($scheme != "https") {
return 301 https://www.yourdomain.com$request_uri;
} # managed by Certbot
}