5

FYI - I suspect this has a very obvious/simple answer (I'm new to nginx)

I am using dynamic upstreams as part of my Nginx config. This means using variables in the proxy_pass directive, which instructs nginx to use a resolver instead of crashing/not-booting if an upstream has a problem (unknown host / not connectable).

However, this seems to also change handling of proxy_pass with a URI. Rather than replacing with the request URI with the URI specified in the proxy_pass directive, it appears to ignore the request URI. I'm searching for a method to preserve (or reproduce) the original behavior that allows me to continue using dynamic hosts.

I have attempted to create a minimal example config here:

server {
    listen 80;
    server_name my-server.com;

    # My chosen DNS server (in this case, the Docker DNS)
    resolver 127.0.0.11 valid=30s ipv6=off;

    # This works
    location / {
        set $upstream frontend:8080;
        proxy_pass http://$upstream;
    }

    # This does not work :-( 
    # The original URI (e.g. /api/users/tommy) is ignored, and 
    # all requests to api-server are directly to /api/
    location /api/ {
        set $upstream api-server:8002;
        proxy_pass http://$upstream/api/;
    }
}

One workaround is to drop the URI from the proxy_pass directive and have the upstream server listen on the exact URI needed. This is not ideal, as a core benefit of a gateway server is adding some flexibility to change things independently (rewriting URIs if needed)

For example,

    # This kind of works, but upstream must listen on /api 
    location /api {
        set $upstream api-server:8002;
        proxy_pass http://$upstream;
    }
6

The documentation states that if you use variables in the proxy_pass directive and you specify a URI part, it will be passed upstream "as is".

You will need to capture the part of the URI you need to send upstream. Either use a regular expression location block, for example:

location ~ ^/api(.*)$ {
    set $upstream ...;
    proxy_pass http://$upstream$1;
}

Or use a rewrite...break to change the current URI, for example:

location /api {
    set $upstream ...;
    rewrite ^/api(.*)$ $1 break;
    proxy_pass http://$upstream;
}
| improve this answer | |
  • Ouch, RTFM. Thanks or the tip on what I missed! – Hamy Jul 14 '19 at 16:17

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.