Skip to content

Reverse Proxy Guide: Using Nginx

This guide will teach you how to install and configure Nginx as a reverse proxy server. A reverse proxy is a critical component in modern web architecture that receives requests from clients, forwards them to one or more backend servers, and then returns the backend's response to the client.

Why Use a Reverse Proxy?

A reverse proxy sits between clients and backend services, offering numerous benefits:

  • Load Balancing: Distributes traffic across multiple backend servers to improve the availability and reliability of your website.
  • Enhanced Security: Hides the true IP addresses of your backend servers, protecting them from direct exposure to the internet. It can centralize security policies, like defending against DDoS attacks.
  • SSL/TLS Termination: Centralizes the management of SSL/TLS certificates, providing HTTPS encryption for all backend services, which simplifies configuration as the services themselves don't have to handle encryption.
  • Caching Static Content: Caches static files (like images, CSS, JS) to reduce the load on backend servers and speed up access for clients.
  • URL Rewriting and Routing: Routes requests to different backend services based on the URL, enabling a more flexible architecture.

Step 1: Install Nginx

First, install Nginx on your Debian server.

bash
sudo apt-get update
sudo apt-get install nginx

After installation, the Nginx service will start automatically. You can confirm this by visiting your server's IP address (http://<your_server_ip>). If you see the Nginx welcome page, the installation was successful.

Don't forget to allow HTTP and HTTPS traffic in your firewall:

bash
sudo ufw allow 'Nginx Full'

Step 2: Configure a Basic Reverse Proxy

Suppose you have an application running locally and listening on port 3000 (e.g., a Node.js or Python web app). We want to use Nginx to proxy public traffic from port 80 to this application.

2.1 Create an Nginx Server Block Configuration File

The best practice for Nginx is to create a separate configuration file for each site or application in the /etc/nginx/sites-available/ directory.

We will create a configuration file named myapp.conf for our application. Replace your_domain.com with your domain name, or use your server's IP address if you don't have a domain.

bash
sudo nano /etc/nginx/sites-available/myapp.conf

Paste the following content into the file:

nginx
server {
    listen 80;
    server_name your_domain.com www.your_domain.com;

    location / {
        proxy_pass http://localhost:3000;
        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;
    }
}
  • listen 80;: Listens on the standard HTTP port.
  • server_name: Defines the domain name for this server block.
  • location /: Matches all incoming requests.
  • proxy_pass http://localhost:3000;: This is the core directive. It tells Nginx to forward matched requests to http://localhost:3000.
  • proxy_set_header: These directives pass the original HTTP headers to the backend application, allowing it to get authentic client information (like IP address, domain, protocol) instead of seeing all requests as coming from Nginx.

2.2 Enable the Server Block

For Nginx to load our new configuration, we need to create a symbolic link to it in the /etc/nginx/sites-enabled/ directory.

bash
sudo ln -s /etc/nginx/sites-available/myapp.conf /etc/nginx/sites-enabled/

To avoid conflicts, you can remove the default configuration link (if it still exists):

bash
sudo rm /etc/nginx/sites-enabled/default

2.3 Test and Restart Nginx

Check the Nginx configuration for syntax errors:

bash
sudo nginx -t

If you see the messages syntax is ok and test is successful, everything is fine.

Now, restart Nginx to apply the changes:

bash
sudo systemctl restart nginx

At this point, when you access your server via http://your_domain.com, Nginx should forward the requests to your local application running on port 3000.


Step 3: Host Multiple Applications

Nginx's server block mechanism makes hosting multiple websites or applications very simple. You just need to repeat the following steps:

  1. Create a new configuration file for the second application (e.g., an app running on port 4000), such as /etc/nginx/sites-available/anotherapp.conf.
  2. In that configuration file, use a different server_name (e.g., another_domain.com) and proxy_pass (e.g., http://localhost:4000).
  3. Create a symbolic link for the new configuration file: sudo ln -s /etc/nginx/sites-available/anotherapp.conf /etc/nginx/sites-enabled/.
  4. Test and restart Nginx.

This way, Nginx will determine which server block configuration to use based on the domain name requested by the client (determined by the Host request header), thereby forwarding the request to the correct backend application.