In this guide, we will explain how to redirect the HTTP traffic to HTTPS in Nginx.

Nginx  pronounced “engine x” is a free, open-source, high-performance HTTP and  reverse proxy server responsible for handling the load of some of the  largest sites on the Internet.

If  you are a developer or system administrator, chances are that you’re  dealing with Nginx on a regular basis. One of the most common tasks  you’ll likely perform is redirecting the HTTP traffic to the secured  (HTTPS) version of your website.

Unlike  HTTP, where requests and responses are sent and returned in plaintext,  HTTPS uses TLS/SSL to encrypt the communication between the client and  the server.

There are many benefits of using HTTPS over HTTP, such as:

  • All the data is encrypted in both directions. As a result, sensitive information cannot be read if intercepted.
  • Google Chrome and all other popular browsers will mark your website as safe.
  • HTTPS allows you to use the HTTP/2 protocol, which significantly improves the site performance.
  • Google favors HTTPS websites. Your site will rank better if served via HTTPS.

The  preferred method to redirect HTTP to HTTPS in Nginx is to configure a  separate server block for each version of the site. You should avoid  redirecting the traffic using the if directive, as it may cause unpredictable behavior of the server.

Redirect HTTP to HTTPS per Site

Typically  when an SSL certificate is installed on a domain, you will have two  server blocks for that domain. The first one for the HTTP version of the  site on port 80, and the other for the HTTPS version on port 443.

To redirect a single website to HTTPS open the domain configuration file and make the following changes:

server {
    listen 80;
    server_name justla.me www.justla.me;
    return 301 https://justla.me$request_uri;
}

Let’s break down the code line by line:

  • listen 80 - The server block will listen for incoming connections on port 80 for the specified domain.
  • server_name justla.me www.justla.me - Specifies the server block’s domain names. Make sure you replace it with your domain name.
  • return 301 https://justla.me$request_uri - Redirect the traffic to the HTTPS version of the site. The $request_uri variable is the full original request URI, including the arguments.

Usually,  you will also want to redirect the HTTPS www version of the site to the  non-www or vice versa. The recommended way to do the redirect is to  create a separate server block for both www and non-www versions.

For example, to redirect the HTTPS www requests to non-www, you would use the following configuration:

server {
    listen 80;
    server_name justla.me www.justla.me;
    return 301 https://justla.me$request_uri;
}

server {
    listen 443 ssl http2;
    server_name www.justla.me;

    # . . . other code

    return 301 https://justla.me$request_uri;
}

server {
    listen 443 ssl http2;
    server_name justla.me;

    # . . . other code
}

Whenever you make changes to the configuration files you need to restart or reload the Nginx service for changes to take effect:

sudo systemctl reload nginx 

Redirect All Sites to HTTPS

If  all of the websites hosted on the server are configured to use HTTPS,  and you don’t want to create a separate HTTP server block for each site,  you can create a single catch-all HTTP server block. This block will  redirect all HTTP requests to the appropriate HTTPS blocks.

To  create a single catch-all HTTP block which will redirect the visitors  to the HTTPS version of the site, open the Nginx configuration file and  make the following changes:

server {
	listen 80 default_server;
	listen [::]:80 default_server;
	server_name _;
	return 301 https://$host$request_uri;
}

Let’s analyze the code line by line:

  • listen 80 default_server - Sets this server block as the default (catch-all) block for all unmatched domains.
  • server_name _ - _ is an invalid domain name that never matches any real domain name.
  • return 301 https://$host$request_uri - Redirect the traffic to the corresponding HTTPS server block with status code 301 (Moved Permanently). The $host variable holds the domain name of the request.

For example, if the visitor opens http://example.com/page2 in the browser, Nginx will redirect the request to https://example.com/page2.

If possible, prefer creating a redirection on a per-domain basis instead of a global HTTP to HTTPS redirection.

Conclusion

In Nginx, the preferred way to redirect HTTP to HTTPS is to create a separate server blocks and perform 301 redirect.

If you have any questions or feedback, feel free to leave a comment.