Nginx as a Reverse Proxy on Ubuntu

Nginx as a Reverse Proxy on Ubuntu

Introduction

Efficient server management is crucial. One of the essential tools in a developer’s arsenal is Nginx, a powerful web server that can also act as a reverse proxy. Setting up Nginx as a reverse proxy on an Ubuntu Server can significantly enhance your website’s performance, security, and flexibility. In this guide, we will walk you through the step-by-step process of configuring Nginx as a reverse proxy on Ubuntu, ensuring a seamless flow of data between clients and your web application.

Prerequisites

  1. Ensure your Ubuntu Server is up-to-date. You can do this by running:
sudo apt update
sudo apt upgrade
  1. If you haven’t already installed Nginx, you can do so using the following command:
sudo apt install nginx

Step 1: Configuring Your Web Application

Before setting up Nginx, make sure your web application is up and running. Note down the IP address and port where your application is accessible. For this step I'll be using Sonarqube as an example. (e.g., http://localhost:9000).

Step 2: Configuring Nginx

  1. Create a new configuration file for your reverse proxy. Use the following command to open a new file in the Nginx sites-available directory:
sudo nano /etc/nginx/sites-available/yourdomain.com
  1. After creating and opening the configuration file, populate it with:
server {
    listen 80;
    server_name example.com www.example.com;

    access_log /var/log/nginx/reverse-proxy.access.log;
    error_log /var/log/nginx/reverse-proxy.error.log;

    location / {
        proxy_pass http://localhost:9000;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_cache_bypass $http_upgrade;
        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;
    }
}

Breakdown:

  • listen 80: Specifies that Nginx should listen for incoming HTTP requests on port 80, the standard port for unencrypted web traffic.

  • server_name example.com www.example.com: Defines the server names or domain names that this Nginx server block will respond to, directing requests from these domains to this specific server configuration.

  • access_log anderror_log: These directives specify the log file paths for access and error logs. Logging is crucial for diagnosing issues and monitoring traffic.

  • proxy_pass http://localhost:9000: Directs incoming requests to the specified backend server at http://localhost:9000(Sonarqube for this example), allowing Nginx to act as a reverse proxy, forwarding client requests to the backend server for processing.

  • proxy_http_version 1.1;

    This directive sets the HTTP version for proxy requests. In this case, it's set to version 1.1, which is a commonly used and widely supported version of the HTTP protocol. Setting the HTTP version explicitly can be useful in situations where you want to ensure compatibility and take advantage of specific features introduced in later versions of the protocol.

  • proxy_set_header Upgrade $http_upgrade;

    The Upgrade header is a standard HTTP header that is used to indicate the protocol the server wishes to switch to. In the context of a reverse proxy, this is often used in conjunction with WebSockets. When a client wants to establish a WebSocket connection, it sends an Upgrade header indicating that it wants to upgrade the connection from HTTP to WebSocket. This directive captures the value of the Upgrade header from the client's request and passes it along when making requests to the backend server.

  • proxy_set_header Connection 'upgrade';

    This directive sets the Connection header to 'upgrade'. Similar to the Upgrade header, the Connection header is used to control whether the network connection stays open after the current transaction finishes. Setting it to 'upgrade' informs the server that the client wishes to establish a different protocol (such as WebSocket).

  • proxy_set_header Host $host;

    The Host header is a standard HTTP header that specifies the domain name of the server (useful in virtual hosting). In a reverse proxy configuration, setting this header ensures that the original Host header sent by the client is passed along to the backend server. This is important for virtual hosting setups where multiple domains are served by the same IP address, allowing the backend server to know which domain the client intended to access.

  • proxy_cache_bypass $http_upgrade;

    This directive is often used in scenarios involving caching. When the value of $http_upgrade is non-empty (indicating an "upgrade" request, such as a WebSocket upgrade), the cache is bypassed. This is necessary because WebSocket connections are meant to be persistent and can't be handled by caching mechanisms designed for regular HTTP requests.

  • proxy_set_header X-Real-IP $remote_addr;: Sets the X-Real-IP header to the client's real IP address. This header can be useful for applications to identify the originating client IP, especially when Nginx is behind a load balancer.

  • proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;: Appends the client's IP address to the X-Forwarded-For header. This header helps the backend server identify the original client IP when requests pass through multiple proxy servers.

  • proxy_set_header X-Forwarded-Proto $scheme;: Sets the X-Forwarded-Proto header to the scheme (http or https) used by the client. This header is useful if your application needs to know whether the original request was made over HTTP or HTTPS.

In Unix-like systems, symbolic links (or symlinks) are pointers to files or directories. Here, you are creating a symlink from your configuration file located in /etc/nginx/sites-available/ to the sites-enabled directory. The sites-available directory typically contains all available configuration files, while sites-enabled contains active configurations that Nginx will use. With this symbolic link, you enable the reverse-proxy configuration you created earlier.

sudo ln -s /etc/nginx/sites-available/reverse-proxy /etc/nginx/sites-enabled

Test Your Configuration

Before applying any configuration changes, it's essential to check for syntax errors in your Nginx configuration file. The nginx -t command tests the configuration file for correctness. If there are errors, it will point them out, allowing you to fix them before restarting Nginx.

sudo nginx -t

Restart Nginx

If the test is successful and your configuration file is error-free, you need to restart Nginx for the changes to take effect. Restarting the Nginx service ensures that the new configuration settings are applied and the server begins using the updated configuration.

sudo systemctl restart nginx

Configuring Firewall Settings (Optional)

If you have a firewall enabled (like UFW, the Uncomplicated Firewall), it's essential to allow traffic on port 80. Port 80 is the default port for HTTP traffic. Allowing traffic on this port permits incoming HTTP requests to reach your Nginx server, enabling it to receive and process web requests.

sudo ufw allow 80/tcp

Conclusion

Congratulations, you have successfully configured Nginx as a reverse proxy on your Ubuntu server! This setup enhances your website's security, performance, and flexibility by allowing Nginx to efficiently handle incoming traffic. Mastering server configurations like these is a valuable skill for web developers and administrators, empowering you to create robust and secure web applications.

Stay tuned for the next post, where we'll show you how to make your website super safe with SSL certificates using Certbot. Exciting stuff! Stay with us for the next steps! 🚀🔒