15

I'm trying to get NGINX's resolver to automatically update the DNS resolution cache, so I'm transitioning to using a variable as the proxy_pass value to achieve that. However, when I do use a variable, it makes all requests go to the root endpoint of the request and cuts off any additional paths of the url. Here's my config:

resolver 10.0.0.2 valid=10s;

server {
    listen 80;
    server_name localhost;

    location /api/test-service/ {
        proxy_redirect     off;

        proxy_set_header   X-Real-IP        $remote_addr;
        proxy_set_header   X-Forwarded-For  $proxy_add_x_forwarded_for;

        # If these 2 lines are uncommented, 'http://example.com/api/test-service/test' goes to 'http://example.com/api/test-service/'
        set $pass_url http://test-microservice.example.com:80/;
        proxy_pass  $pass_url;

        # If this line is uncommented, things work as expected. 'http://example.com/api/test-service/test' goes to 'http://example.com/api/test-service/test'
        # proxy_pass  http://test-microservice.example.com:80/;

    }

This doesn't make any sense to me because the hardcoded URL and the value of the variable are identical. Is there something I'm missing?

EDIT: Ah, so I've found the issue. But I'm not entirely sure how to handle it. Since this is a reverse proxy, I need the proxy_pass to REMOVE the /api/test-service/ from the URI before it passes it to the proxy. So..

This:

http://example.com/api/test-service/test

Should proxy to this:

http://test-microservice.example.com:80/test

But instead proxies to this:

http://test-microservice.example.com:80/api/test-service/test

When I'm not using a variable, it drops it no problem. But the variable adds it. Is that just inherently what using the variable will do?

ev0lution37
  • 1,129
  • 2
  • 14
  • 28
  • My take is that this is probably the best way to use nginx (including defining your own resolver servers with appropriate expiry rules). When all you have is the `proxy_pass` intuition, it's really alarming when the routing doesn't work – Avindra Goolcharan Dec 07 '19 at 01:51

1 Answers1

16

There is a small point you missed in documentation

When variables are used in proxy_pass:

location /name/ {
  proxy_pass http://127.0.0.1$request_uri;
}

In this case, if URI is specified in the directive, it is passed to the server as is, replacing the original request URI.

So you config needs to be changed to

set $pass_url http://test-microservice.example.com:80$request_uri;
proxy_pass  $pass_url;
Fez Vrasta
  • 14,110
  • 21
  • 98
  • 160
Tarun Lalwani
  • 142,312
  • 9
  • 204
  • 265
  • 4
    this doesn't work, at least in recent version of nginx. the whole path gets passed on, including the location `/name/`, which OP wanted to be stripped out. – dbzuk Mar 08 '22 at 11:01