While setting up LetsEncrypt to work with CloudFlare, I ran into a bunch of issues with my NginX config that caused me a bunch of downtime. Because I run multiple domains, I wanted to keep my non-www to www URL redirects and also redirect HTTP to HTTPS.
Before, I was using just:
server {
server_name "~^([^.]*\.[^.]*)$";
listen 80;
listen [::]:80;
listen 443 ssl;
listen [::]:443 ssl;
return 301 $scheme://www.$host$request_uri;
}
It’s an incredibly elegant redirect. But it didn’t work well with my HTTPS redirect. So, I changed it to be a bit easier to understand (and more time-consuming to set up), which looks like this:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# NGINX Server Block for: | |
# Redirect non-www base domain (domain.com) to www (www.domain.com) | |
# Redirect HTTP to HTTPS SSL (HTTP2) | |
# Supports multiple domains and subdomains | |
# Created by George Liu (www.georgeliu.me / Github:tgmgroup) | |
# STEP 1 - Base HTTPS Block | |
server { | |
#Listen only on HTTPS, use STEP 3 to redirect from HTTP | |
listen 443 ssl http2; | |
listen [::]:443 ssl http2; | |
# Put Includes Here | |
# Change .domain1.com and .domain2.com to your own domain | |
# The .domain1.com wildcard format (DOT domain) catches all domains and subdomains of domain1.com | |
server_name .domain1.com .domain2.com; | |
# Put Server Configs Here | |
# Put Other Configs Here | |
} | |
# STEP 2 - Redirect base (non-www URL) to HTTPS www | |
server { | |
listen 80; | |
listen [::]:80; | |
listen 443 ssl http2; | |
listen [::]:443 ssl http2; | |
# Catch only www subdomains on HTTP and HTTPS | |
server_name domain1.com domain2.com; | |
# Permanent redirect to HTTPS and www | |
return 301 https://www.$host$request_uri; | |
# Use the following if redirecting www to non-www URLs | |
# server_name www.domain1.com www.domain2.com; | |
# return 301 https://$host$request_uri; | |
# If using both HTTPS and HTTP (only www redirect), edit STEP 1 to include | |
# listen 80; | |
# listen [::]:80; | |
# and remove STEP 3 | |
# and change the return 301 line to use "$scheme://" instead of "https://" | |
} | |
# STEP 3 - Redirect all non- base-non-www HTTP to HTTPS | |
server { | |
listen 80; | |
listen [::]:80; | |
# Catch all base and subdomains on HTTP, including redirects from STEP 2 | |
server_name .domain1.com .domain2.com; | |
# If user prefers, use "www.domain1.com *.domain1.com" combination instead of | |
# ".domain1.com" wildcard to avoid NGINX warnings | |
return 301 https://$host$request_uri; | |
} |
Don’t forget the linux commands to edit and restart NginX
sudo nano /etc/nginx/sites-enabled/(config)
sudo nginx -t && sudo service nginx restart (OR) sudo systemctl restart nginx
And don’t forget to change your DNS settings at your DNS provider:
add a CNAME record: www
as name and @
as hostname