Read in 5 minutes

last updated 

Setting up an Nginx Reverse Proxy

A reverse proxy is a service that takes a client request, sends the request to one or more proxied servers, fetches the response, and delivers the server’s response to the client.

Because of its performance and scalability, NGINX is often used as a reverse proxy for HTTP and non-HTTP servers. A common reverse proxy configuration is to put Nginx in front of Node.js, Python or Java applications.

Using Nginx as a reverse proxy gives you several additional benefits:

  • Load Balancing - Nginx can perform load balancing to distribute clients’ requests across proxied servers which improve the performance, scalability, and reliability.
  • Caching - Nginx can cache the content received from the proxied servers’ responses and use it to respond to clients without having to contact the proxied server for the same content every time.
  • SSL Termination - Nginx can act as an SSL endpoint for connections with the clients. It will handle and decrypt incoming SSL connections and encrypt the proxied server’s responses.
  • Compression - If the proxied server does not send compressed responses, you can configure Nginx to compress the responses before sending them to the clients.

This tutorial outlines the steps on how to configure Nginx as a reverse proxy.

Prerequisites

We are assuming that you have Nginx installed on your Ubuntu, CentOS or Debian server.

Using Nginx as a Reverse Proxy

To configure Nginx as a reverse proxy to an HTTP server, open the domain’s server block configuration file and specify a location and a proxied server inside of it:

server {
    listen 80;
    server_name www.example.com example.com;

    location /app {
       proxy_pass http://127.0.0.1:8080;
    }
}

The proxied server URL is specified using the proxy_pass directive and can use HTTP or HTTPS as protocol, and domain name or IP address, and an optional port and URI as an address.

The configuration above tells Nginx to pass all requests to the /app location to the proxied server at http://127.0.0.1:8080.

On Ubuntu and Debian based distributions server block files are stored in the /etc/nginx/sites-available directory, while on CentOS in /etc/nginx/conf.d directory.

To better illustrate how location and proxy_pass directives work, let’s take the following example:

server {
    listen 80;
    server_name www.example.com example.com;

    location /blog {
       proxy_pass http://node1.com:8000/wordpress/;
    }
}

If a visitor access http://example.com/blog/my-post, Nginx will proxy this request to http://node1.com:8000/wordpress/my-post.

When the address of the proxied server contains a URI, /wordpress/, the request URI that is passed to the proxied server is replaced by a URI specified in the directive. If the address of the proxied server is specified without a URI the full request URI is passed to the proxied server.

Passing Request Headers

When Nginx proxies a request, it automatically defines two header fields in a proxied requests from the client, Host and Connection and removes empty headers. Host is set to the $proxy_host variable, and Connection is set to close.

To adjust or set headers for proxied connections, use the proxy_set_header directive followed by the header value. You can find a list of all available Request Headers and their allowed values here. If you want to prevent a header from being passed to the proxied server, set it to an empty string "".

In the following example, we are changing the value of the Host header field to $host and removing the Accept-Encoding header field by setting its value to an empty string.

location / {
    proxy_set_header Host $host;
    proxy_set_header Accept-Encoding "";
    proxy_pass http://localhost:3000;
}

Configuring Nginx as a Reverse Proxy to a non-HTTP proxied server

To configure Nginx as a reverse proxy to a non-HTTP proxied server, you can use the following directives:

  • fastcgi_pass - reverse proxy to a FastCGI server.
  • uwsgi_pass - reverse proxy to a uwsgi server.
  • scgi_pass - reverse proxy to an SCGI server.
  • memcached_pass - reverse proxy to a memcached server.

One of the most common examples is to use Nginx as a reverse proxy to PHP-FPM:

server {

    # ... other directives

    location ~ \.php$ {
        include snippets/fastcgi-php.conf;
        fastcgi_pass unix:/run/php/php7.2-fpm.sock;
    }
}

Common Nginx Reverse Proxy Options

Serving content over HTTPS has become a standard nowadays. In this section, we will give you an example of HTTPS Nginx reverse proxy configuration including the recommended Nginx proxy parameters and headers.

  location/ {
    proxy_pass http://127.0.0.1:3000;
    proxy_http_version  1.1;
    proxy_cache_bypass  $http_upgrade;

    proxy_set_header Upgrade           $http_upgrade;
    proxy_set_header Connection        "upgrade";
    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;
    proxy_set_header X-Forwarded-Host  $host;
    proxy_set_header X-Forwarded-Port  $server_port;
  }
  • proxy_http_version 1.1 - Defines the HTTP protocol version for proxying, by default it it set to 1.0. For Websockets and keepalive connections you need to use the version 1.1.
  • proxy_cache_bypass $http_upgrade - Sets conditions under which the response will not be taken from a cache.
  • Upgrade $http_upgrade and Connection "upgrade" - These header fields are required if your application is using Websockets.
  • Host $host - The $host variable in the following order of precedence contains: host name from the request line, or host name from the Host request header field, or the server name matching a request.
  • X-Real-IP $remote_addr - Forwards the real visitor remote IP address to the proxied server.
  • X-Forwarded-For $proxy_add_x_forwarded_for - A list containing the IP addresses of every server the client has been proxied through.
  • X-Forwarded-Proto $scheme - When used inside HTTPS server block each HTTP response from the proxied server will be rewritten to HTTPS.
  • X-Forwarded-Host $host - Defines the original host requested by the client.
  • X-Forwarded-Port $server_port - Defines the original port requested by the client.

If you don’t have an existing SSL/TLS certificate, you can use certbot to obtain a free Let’s Encrypt SSL certificate on your Ubuntu 18.04, CentOS 7, or Debian server.

Conclusion

You have learned how to use Nginx as a Reverse Proxy. We have also shown you how to pass additional parameters to the server and to modify and set different header fields in proxied requests.