How To Preserve Original URL With Nginx Proxy_Pass?

Published September 5, 2024

Problem: Preserving Original URLs with Nginx Proxy_Pass

When you use Nginx's proxy_pass directive, the original URL structure might be lost during request forwarding. This can cause problems with routing, application functionality, and search engine optimization. Keeping the original URL structure while using proxy_pass is a common issue in Nginx configuration.

Nginx Configuration Solution

Using proxy_set_header Directive

The proxy_set_header directive helps preserve the original URL when using Nginx's proxy_pass. This directive lets you set or change request header fields sent to the proxied server.

To keep the original URL, you can use proxy_set_header to set the Host header. The Host header tells the proxied server which domain name to use for processing the request. Setting this header to the original host makes sure the proxied server gets the right information about the original request.

Here's how proxy_set_header helps preserve the original URL:

  1. It sets the Host header to the $host variable, which has the original request's host name.
  2. This makes sure your Thin or Unicorn app server gets the correct host information.
  3. With the right host information, your application can handle routing and process the request as if it came directly from the client.

By using proxy_set_header with proxy_pass, you can forward requests to your application server while keeping the original URL structure. This fixes the issue of Nginx changing the URL during proxying, allowing your application to work as expected.

Example: Setting up proxy_set_header in Nginx

server {
    listen 80;
    server_name example.com;

    location / {
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_pass http://backend_server;
    }
}

In this example, we set the Host header to $host, which preserves the original host name. We also set X-Real-IP to pass the client's IP address to the backend server.

Implementing the Solution

Configuring Nginx

To implement the solution and keep the original URL when using Nginx's proxy_pass, follow these steps to change your Nginx configuration:

  1. Open your Nginx configuration file. It's usually at /etc/nginx/nginx.conf or /etc/nginx/sites-available/your_site_config.

  2. Find the server block for your website.

  3. In the server block, find or create a location block that matches the path you want to proxy.

  4. Add the proxy_set_header directive to set the Host header.

  5. Include the proxy_pass directive to send requests to your backend server.

Here's an example configuration block:

server {
    listen 80;
    server_name yourdomain.com;

    location / {
        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_pass http://your_backend_server;
    }
}

In this configuration:

  • proxy_set_header Host $host; keeps the original host name.
  • proxy_set_header X-Real-IP $remote_addr; sends the client's IP address.
  • proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; adds the client's IP to the X-Forwarded-For header.
  • proxy_set_header X-Forwarded-Proto $scheme; sends the original protocol (http or https).
  • proxy_pass http://your_backend_server; sends requests to your backend server.

Replace yourdomain.com with your actual domain name and http://your_backend_server with the address of your Thin or Unicorn app server.

After making these changes, save the configuration file and restart Nginx to apply the new settings.

Tip: Testing Your Configuration

After making changes to your Nginx configuration, it's a good practice to test it before restarting the server. You can do this by running:

nginx -t

This command checks the syntax of your configuration files and reports any errors. If the test is successful, you can then safely restart Nginx.

Testing and Verification

After implementing the Nginx configuration changes to preserve the original URL, test and verify that the solution works. Here are some methods to confirm that the original URL is preserved and fix common issues:

  1. Use curl to test requests:

    • Run a curl command from your local machine or a separate server to send requests to your Nginx server.
    • Example: curl -I http://yourdomain.com/some/path
    • Check the response headers to see if the Host header matches your domain.
  2. Check server logs:

    • Review your Nginx access logs (usually in /var/log/nginx/access.log).
    • Look for entries that show the correct original URL in the request line.
  3. Use browser developer tools:

    • Open your website in a web browser and use the developer tools (usually F12).
    • Go to the Network tab and inspect the requests.
    • Verify that the Request URL and Host header match your original domain.
  4. Monitor backend server logs:

    • Check the logs of your Thin or Unicorn app server.
    • Confirm that the incoming requests show the correct original URL.
  5. Test different URL paths:

    • Try accessing various paths on your website to see if all routes work correctly.
    • Pay attention to any custom routing logic in your application.

Tip: Use a test environment

Set up a staging or test environment that mirrors your production setup. This allows you to test configuration changes safely without affecting your live site. Use tools like Docker to create isolated environments for testing Nginx configurations.

Fixing common issues:

  1. Incorrect Host header:

    • If the Host header is wrong, check your proxy_set_header Host $host; directive in the Nginx configuration.
    • Make sure no conflicting directives override this setting.
  2. URL rewriting issues:

    • If you notice unexpected URL changes, review any rewrite directives in your Nginx configuration.
    • Make sure that rewrites do not interfere with your proxy_pass setup.
  3. SSL/TLS problems:

    • For HTTPS sites, verify that your SSL/TLS configuration is correct.
    • Check that the X-Forwarded-Proto header is set correctly for secure connections.
  4. Caching issues:

    • If you're using caching, clear both browser and server caches to see the most recent configuration changes.
  5. Backend server configuration:

    • Verify that your Thin or Unicorn app server is set up to use the information from the proxy headers.
    • Check that the application code handles the original URL structure correctly.