← Build logs
InfraMay 28, 2026

Nginx Configuration Change: Isolating /api/me/* Requests to Port 3001 for API Routing Optimization

I needed to optimize my API routing and strengthen service isolation. I identified a few areas for improvement in my existing infrastructure setup and decided to modify my Nginx configuration. Specifically, I wanted to route requests for certain APIs, like /api/me/*, to a separate port for management.

Attempt and Pitfall

Initially, I tried a simple approach by adding a location block. I intended to pass requests coming to /api/me/ to http://localhost:3001 using proxy_pass.

server {
    listen 80;
    server_name example.com;

    location /api/me/ {
        proxy_pass http://localhost:3001;
        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;
    }

    location / {
        proxy_pass http://localhost:3000; # Other APIs
        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;
    }
}

The problem was that the paths following /api/me/ weren't being passed correctly. For example, a request to /api/me/profile would only be forwarded to http://localhost:3001/, resulting in a 404 error. I hadn't fully grasped how Nginx's location blocks work. After about 3 hours of trial and error, I realized my understanding of how location blocks match paths was insufficient.

The Cause

Nginx's location blocks, by default, use prefix matching. While location /api/me/ matches any path starting with /api/me/, it had the issue of appending the matched part to the URL specified in proxy_pass, rather than passing the remaining path correctly. To preserve the path following /api/me/, additional consideration was needed for the proxy_pass configuration.

The Solution

To resolve this, I changed the location block's path to use a regular expression and employed the rewrite directive to rewrite the path. I modified the configuration to accurately proxy requests starting with /api/me/ to http://localhost:3001/.

server {
    listen 80;
    server_name example.com;

    location ~ ^/api/me/(.*)$ {
        proxy_pass http://localhost:3001/$1;
        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;
    }

    location / {
        proxy_pass http://localhost:3000; # Other APIs
        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;
    }
}

The regular expression ~ ^/api/me/(.*)$ matches any string starting with /api/me/, followed by any characters ((.*)). Then, $1 is appended to the URL in proxy_pass, ensuring that the remainder of the original request path is passed through correctly.

Results

  • Requests to /api/me/* were successfully isolated to the localhost:3001 port.
  • API routing was optimized, leading to more efficient request handling.
  • Service isolation was strengthened, minimizing the impact of an outage in one API on other services.

Key Takeaways — Avoiding the Same Trap

  • [ ] Accurately understand Nginx's location block path matching behavior (prefix vs. regular expression).
  • [ ] When rewriting paths with proxy_pass, consider using the rewrite directive or regular expression capture groups ($1).
  • [ ] When separating specific path patterns, the order and priority of location blocks are also important.
  • [ ] After making changes, always test with various paths to ensure they function as expected.