How to Strip Path Prefix in Nginx proxy_pass for Clean URL Routing


2 views

When using Nginx's proxy_pass to route subpaths to different backend services, the original path (/en in this case) gets forwarded to the upstream server by default. This creates routing issues when the backend application expects requests at root level (/).

Here are the most reliable approaches to solve this path prefix issue:

# Solution 1: Rewrite before proxy_pass
location /en/ {
    rewrite ^/en/(.*) /$1 break;
    proxy_pass http://luscious;
}

# Solution 2: Trailing slash in proxy_pass
location /en/ {
    proxy_pass http://luscious/;  # Note the trailing slash
}

# Solution 3: Using variables
location /en/ {
    proxy_pass http://luscious$request_uri;
    proxy_set_header X-Original-URI $request_uri;
}

For most use cases, Solution 2 provides the cleanest implementation:

upstream luscious_backend {
    server backend.example.com:8000;
}

server {
    listen 80;
    server_name example.com;

    location /en/ {
        proxy_pass http://luscious_backend/;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        
        # Optional: Remove /en prefix from other headers
        proxy_redirect http://luscious_backend/ /en/;
    }
}
  • Forgetting the trailing slash in either location or proxy_pass
  • Not handling static assets paths correctly
  • Mixing rewrite rules with proxy_pass unnecessarily
  • Ignoring header modifications needed for the backend

For more complex routing scenarios:

location ~ ^/(en|fr|de)(/.*)?$ {
    set $lang $1;
    set $path $2;
    
    proxy_pass http://backend_servers/$path$is_args$args;
    proxy_set_header X-Language $lang;
}

When implementing reverse proxy with Nginx, a common challenge arises when you need to "mount" an application under a specific path while the upstream server expects requests at its root path. Consider this scenario:

upstream luscious {
  server lixxxx.members.linode.com:9001;
}

server {
  root /var/www/example.com/current/public/;
  server_name example.com;

  location /en {
    proxy_pass http://luscious;
  }
}

Accessing example.com/en results in a 404 error because the upstream server receives the request with the /en path prefix, which doesn't exist on the backend application.

The most elegant solution is to modify the proxy_pass directive to strip the /en prefix before forwarding to the upstream server:

location /en {
  proxy_pass http://luscious/;
}

Notice the trailing slash after the upstream name. This simple change tells Nginx to replace the matched /en path with / when forwarding the request.

For more complex scenarios where you need to preserve part of the path or perform pattern-based rewriting, you can use regular expressions:

location ~ ^/en(/.*)$ {
  proxy_pass http://luscious$1;
}

This configuration will:

  • Match any path starting with /en
  • Capture the remaining path in $1
  • Proxy to the upstream server with just the captured portion

Here's a production-ready configuration that includes common proxy settings:

upstream backend_app {
  server backend.example.com:8080;
  keepalive 32;
}

server {
  listen 80;
  server_name example.com;

  location /en/ {
    proxy_pass http://backend_app/;
    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;
    
    # Timeout settings
    proxy_connect_timeout 60s;
    proxy_read_timeout 60s;
    proxy_send_timeout 60s;
    
    # Buffering settings
    proxy_buffering on;
    proxy_buffer_size 4k;
    proxy_buffers 8 16k;
  }
}

When implementing path rewriting with Nginx proxy_pass, watch out for these issues:

  • Missing trailing slash: proxy_pass http://backend vs proxy_pass http://backend/ behave differently
  • Double slashes: Ensure your rewritten path doesn't create invalid URLs like http://backend//path
  • Header preservation: Always forward the Host header to prevent routing issues

To debug proxy issues, examine the request headers received by your upstream server or add these to your Nginx config:

location /en {
  add_header X-Proxied-Path $request_uri;
  proxy_pass http://luscious/;
}