DEV Community

Shakhzhakhan Maxudbek
Shakhzhakhan Maxudbek

Posted on Edited on Originally published at args.tech

Nginx Reverse Proxy with SSL & HTTP to HTTPS Redirect

Introduction

Nginx is a powerful, high-performance web server and reverse proxy. While its primary goal is serving static content, it is frequently used as a reverse proxy to sit in front of application servers (like Python/Django, Node.js, or Go) to handle incoming traffic, load balancing, and SSL termination.

In this tutorial, we will configure Nginx as a reverse proxy for a web application running on port 8000. We will also secure the traffic by generating a self-signed SSL certificate and forcing a redirect from HTTP to HTTPS using HSTS (HTTP Strict Transport Security) principles.

Step 1: Install Nginx

First, ensure your package manager is up to date and install the web server.

Update package index:

sudo apt update
Enter fullscreen mode Exit fullscreen mode

Install Nginx from the official repositories:

sudo apt install nginx -y
Enter fullscreen mode Exit fullscreen mode

Step 2: Configure firewall

If you are using UFW (Uncomplicated Firewall), you need to allow traffic on both HTTP (port 80) and HTTPS (port 443). Nginx provides a profile for this.

Allow Nginx full access:

sudo ufw allow 'Nginx Full'
Enter fullscreen mode Exit fullscreen mode

Step 3: Generate SSL certificate

For this tutorial, we will create a self-signed certificate. This is useful for testing, development environments, or internal services.

Important Note: Self-signed certificates will cause Privacy Error warnings in browsers because they are not signed by a trusted Certificate Authority. For a production website accessible to the public, you should use a trusted certificate.

For instructions on obtaining a free trusted certificate, see: How to Secure Nginx with Let's Encrypt on Debian and Ubuntu.

If you still wish to proceed with a self-signed certificate for testing purposes, use OpenSSL.

Generate the certificate and key (valid for 365 days):

sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /etc/ssl/private/nginx-selfsigned.key -out /etc/ssl/certs/nginx-selfsigned.crt
Enter fullscreen mode Exit fullscreen mode

The command will ask for details like Country, State, and Organization. You can fill them in or leave them blank, but ensure the Common Name (CN) matches your server's IP address or domain name.

Step 4: Configure Nginx as reverse proxy

Now we will create a configuration file that does two things:

  1. Redirects all unencrypted HTTP traffic to HTTPS.
  2. Proxies the secure HTTPS traffic to your backend application running on localhost:8000.

Create a new configuration file for your project:

sudo nano /etc/nginx/sites-available/your-project.com
Enter fullscreen mode Exit fullscreen mode

Add the following configuration (pay attention to the comments explaining the parameters):

server {
    # Block for handling standard HTTP traffic (Port 80)
    listen 80;
    server_name your-project.com www.your-project.com;

    # Force redirect all traffic to HTTPS
    # 301 Moved Permanently is best for SEO and caching
    return 301 https://$host$request_uri;
}

server {
    # Block for handling HTTPS traffic (Port 443)
    listen 443 ssl;
    server_name your-project.com www.your-project.com;

    # SSL Configuration
    # Paths must match the files we generated in Step 3
    ssl_certificate /etc/ssl/certs/nginx-selfsigned.crt;
    ssl_certificate_key /etc/ssl/private/nginx-selfsigned.key;

    # Reverse Proxy Configuration
    location / {
        # Pass the request to the application server (e.g., Gunicorn/Django)
        proxy_pass http://localhost:8000;

        # Forward original client headers to the application
        # This is crucial for the app to know the real client IP and protocol
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}
Enter fullscreen mode Exit fullscreen mode

Save and close the file.

Step 5: Enable configuration

To enable the site, create a symbolic link from sites-available to sites-enabled.

Link the configuration file:

sudo ln -s /etc/nginx/sites-available/your-project.com /etc/nginx/sites-enabled/
Enter fullscreen mode Exit fullscreen mode

Before restarting, always check the Nginx configuration for syntax errors.

Test Nginx configuration:

sudo nginx -t
Enter fullscreen mode Exit fullscreen mode

You should see an output confirming the syntax is ok and the test is successful.

Restart Nginx to apply changes:

sudo systemctl restart nginx
Enter fullscreen mode Exit fullscreen mode

Conclusion

Your Nginx server is now configured. When you visit your domain via http://, you will be automatically redirected to https://.

Since we used a self-signed certificate, your browser will display a warning (e.g., Your connection is not private). This is expected behavior. You can click Advanced and Proceed to access your site. For public users, remember to replace this with a Let's Encrypt certificate as mentioned in Step 3.

Did this save you an hour of debugging? Writing high-quality tech guides takes hours of research and testing. If you found this post valuable, you can support my work by buying me a coffee. Thank you!

Buy Me a Coffee at ko-fi.com

Top comments (0)