Nginx Configuration Setting up a Reverse Proxy
Tags: nginx, reverseproxy, microservices, opensource
Published: 2023-09-17 07:49:49

In this article, As some of you may know, Nginx is a web server and reverse proxy server capable of handling incoming HTTP requests and distributing them to multiple back-end servers. I will show you how I set up a reverse proxy using the [nginx.conf](https://github.com/mehmetkirkoca/social-media-manager/blob/main/nginx.conf) file for the [social media manager project](https://github.com/mehmetkirkoca/social-media-manager) I am working on. We have four locations: two of them belong to the UI service, one is for the socket.io service, and the last one is for API calls.

This is the real-world scenario I’m utilizing for my social media manager project with this configuration.

```
events {}
http {
  server {
    listen 80;
    server_name localhost;
    location / {
        proxy_pass http://ui:5173;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
    }
    location /ws {
        proxy_pass http://ui:5173;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
    }
    location /socket.io/ {
      proxy_http_version 1.1;
      proxy_set_header Upgrade $http_upgrade;
      proxy_set_header Connection "upgrade";
      proxy_pass  http://socket:8084/socket.io/;
    }
    location /api/ {
      rewrite ^/api/(.*) /$1 break;
      proxy_pass http://gateway:8084;
      proxy_set_header Host $host;
      proxy_set_header X-Real-IP $remote_addr;
    }
  }
}
```

**Basic Nginx Structure**

An Nginx configuration is organized into blocks: http, server, and location.

**1. Starting an HTTP Block:**
http { … } block defines the start of an HTTP server configuration.

**2. Defining a Server Block:**
The ‘server { … }’ block is your command center, providing configuration settings for a specific server. The ‘listen’ directive is your server’s attentive ear, indicating which port to tune into — usually, it’s 80, the standard for HTTP communication. But what about the ‘server_name’? It’s your online identity, specifying your domain name, which in our case is simply, “localhost”.

**3. Location Blocks:**
location blocks determine how Nginx handles requests based on their URL path. / location handles requests to the root (“/”) and proxies them to a front-end named “ui” on port 5173.

**Proxying Requests:**
proxy_pass directive forwards requests to the specified webservice.

proxy_set_header is an essential component of setting up a reverse proxy in Nginx configuration. When you use this directive, you’re essentially defining HTTP headers to the request sent to the proxied servers.

**Specific Functions of proxy_set_header**

**Host:** The host is one of the header fields in an HTTP request, and this represents the host and port number of the server to which the request is being sent. In the context of proxy_set_header, it refers to the host for which the request should appear to be intended.

**X-Real-IP:** This, on the other hand, is used to give the server information about the client’s IP address. Typically, when there’s a proxy in the mix, the client’s IP address can get lost. However, proxy_set_header can send this in a header, so the server knows.

**Upgrade:** The connection can then “upgrade” from HTTP to a different protocol such as WebSocket. This is triggered by the client sending an Upgrade request header in its HTTP request.

**Connection:** Ensures the connection is maintained during the upgrade

**Using proxy_set_header**
Here’s an example of how you might use the proxy_set_header directive:

`proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';`

These settings aid in maintaining the original client’s address even when requests are being made through a proxy server, as the HTTP header would carry the IP address in the form of the X-real-IP. Plus, it helps set up a seamless WebSocket connection.

In summary, proxy_set_header serves a critical role in setting up a reverse proxy configuration with Nginx. It not only maintains the request’s integrity but also enables advanced features like WebSocket support.

sets HTTP headers for proxying, such as Host, X-Real-IP, and headers needed for WebSocket support.

**Handling WebSocket Requests:**
WebSocket connections are enabled using proxy_http_version, Upgrade, and Connection headers. The second location /ws block handles WebSocket requests and forwards them similarly to the “ui” backend.

**Handling Specific Routes:**
The third location /socket.io/ block forwards requests to a different backend service on port 8084, intended for WebSocket communication.

**Rewriting URL Paths:**
The fourth location /api/ block rewrites URL paths, removing the “/api” prefix, and proxies requests to a “gateway” backend.

**Conclusion:**
If you’re orchestrating multiple services, Nginx as a reverse proxy simplifies communication. Try it and supercharge your project!

What do you think about using Nginx as a reverse proxy? Share your thoughts and experiences in the comments below!