Skip to Content

How to Use Nginx to Access Other Systems with proxy_pass

Nginx is a popular web server that can also act as a reverse proxy, load balancer, and HTTP cache. One of the features of Nginx is the ability to use proxy_pass to forward requests to other servers or systems. This can be useful for various scenarios, such as:

  • Serving static files from a different server or location
  • Routing requests to different backend servers based on the request URI
  • Bypassing firewall restrictions or network limitations
  • Hiding the real IP address or domain name of the backend server
  • Enhancing security or performance by adding SSL encryption, caching, or compression

In this article, we will show you how to use Nginx to access other systems with proxy_pass. We will also cover some common issues and solutions that you may encounter when using this feature.

What is proxy_pass and how does it work?

The proxy_pass directive is used to specify the URL of a server or system that will handle the request. It can be used inside a location, server, or http block in the Nginx configuration file. For example:

location / {
    proxy_pass http://example.com;
}

This means that any request that matches the location / will be forwarded to http://example.com. The proxy_pass directive can also accept variables, such as $request_uri, $args, or $scheme. For example:

location / {
    proxy_pass http://$http_host$request_uri;
}

This means that any request that matches the location / will be forwarded to the same host and URI as the original request.

When Nginx forwards a request to another system with proxy_pass, it also passes some headers to the backend server, such as:

  • Host: The value of the proxy_pass directive, unless overwritten by proxy_set_header
  • X-Real-IP: The IP address of the client
  • X-Forwarded-For: A list of IP addresses of all proxies involved in the request
  • X-Forwarded-Proto: The protocol (http or https) of the original request

These headers can be useful for the backend server to identify the original client and the proxy chain. They can also be modified or removed by using proxy_set_header or proxy_hide_header directives.

How to use Nginx to access other systems with proxy_pass

To use Nginx to access other systems with proxy_pass, you need to do the following steps:

  1. Install and configure Nginx on your server
  2. Create a location block for each system you want to access
  3. Specify the URL of the system with proxy_pass inside the location block
  4. Optionally, adjust other proxy settings, such as headers, caching, buffering, timeouts, etc.
  5. Reload or restart Nginx to apply the changes

Let’s see an example of how to use Nginx to access other systems with proxy_pass.

Example: Accessing a local system with proxy_pass

Suppose you have a local system running on port 8080 that you want to access from outside your network. You can use Nginx as a reverse proxy to forward requests from port 80 (the default HTTP port) to port 8080. Here’s how:

  1. Install and configure Nginx on your server. You can follow this guide for Ubuntu or this guide for CentOS.
  2. Create a location block for your local system in the default server block (or any other server block you want). For example:
server {
    listen 80 default_server;
    listen [::]:80 default_server;

    # ...

    location / {
        proxy_pass http://localhost:8080;
    }
}
  1. Specify the URL of your local system with proxy_pass inside the location block. In this case, it’s http://localhost:8080.
  2. Optionally, adjust other proxy settings, such as headers, caching, buffering, timeouts, etc. For example, you may want to set the Host header to match your domain name instead of localhost:
location / {
    proxy_pass http://localhost:8080;
    proxy_set_header Host $host;
}
  1. Reload or restart Nginx to apply the changes. You can use this command for Ubuntu or this command for CentOS:
sudo systemctl reload nginx

Now you should be able to access your local system from outside your network by using your server’s IP address or domain name.

Common issues and solutions when using proxy_pass

Using Nginx to access other systems with proxy_pass can sometimes result in unexpected errors or behaviors. Here are some common issues and solutions that you may encounter when using this feature.

Issue: The request URI is appended twice

If you use a trailing slash in both the location and the proxy_pass directives, Nginx will append the request URI twice to the backend server. For example:

location / {
    proxy_pass http://example.com/;
}

If you request http://yourserver.com/foo, Nginx will forward it to http://example.com/foo/foo, which is probably not what you want.

Solution: Remove the trailing slash from either the location or the proxy_pass directive. For example:

location / {
    proxy_pass http://example.com;
}

Or:

location / {
    proxy_pass http://example.com/;
}

Issue: The request URI is not passed at all

If you use a URI in the proxy_pass directive, Nginx will replace the request URI with the one specified in the proxy_pass directive. For example:

location / {
    proxy_pass http://example.com/bar;
}

If you request http://yourserver.com/foo, Nginx will forward it to http://example.com/bar, which is probably not what you want.

Solution: Use a variable in the proxy_pass directive to preserve the request URI. For example:

location / {
    proxy_pass http://example.com$uri;
}

Or:

location / {
    proxy_pass http://example.com$request_uri;
}

Issue: The backend server returns a 404 error

If the backend server expects a different URI than the one passed by Nginx, it may return a 404 error. For example, if the backend server expects a URI starting with /blog, but Nginx passes a URI starting with /, the backend server may not find the requested resource.

Solution: Use a rewrite directive to modify the request URI before passing it to the backend server. For example:

location / {
    rewrite ^/(.*)$ /blog/$1 break;
    proxy_pass http://example.com;
}

This will prepend /blog to the request URI before forwarding it to http://example.com.

Frequently Asked Questions (FAQ)

Here are some frequently asked questions related to using Nginx to access other systems with proxy_pass.

Q: How can I use Nginx to access other systems with different protocols, such as HTTPS or WebSocket?

A: You can use Nginx to access other systems with different protocols by specifying the protocol in the proxy_pass directive. For example, to access a system with HTTPS, you can use:

proxy_pass https://example.com;

To access a system with WebSocket, you can use:

proxy_pass http://example.com;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";

Q: How can I use Nginx to access other systems with authentication?

A: You can use Nginx to access other systems with authentication by adding the Authorization header to the proxy_pass directive. For example, to access a system with basic authentication, you can use:

proxy_pass http://example.com;
proxy_set_header Authorization "Basic dXNlcm5hbWU6cGFzc3dvcmQ=";

Where dXNlcm5hbWU6cGFzc3dvcmQ= is the base64-encoded username and password.

Q: How can I use Nginx to access multiple systems with proxy_pass?

A: You can use Nginx to access multiple systems with proxy_pass by creating multiple location blocks or using an upstream block. For example, to access different systems based on the request URI, you can use:

location /foo {
    proxy_pass http://foo.example.com;
}

location /bar {
    proxy_pass http://bar.example.com;
}

Or, to access different systems based on load balancing or failover, you can use:

upstream backend {
    server foo.example.com;
    server bar.example.com backup;
}

location / {
    proxy_pass http://backend;
}

Disclaimer

This article is for informational purposes only and does not constitute professional advice. The author and publisher are not responsible for any damages or losses that may result from using or relying on the information in this article. Always consult a qualified professional before making any decisions related to your web server configuration or security.