NGINX: can I use a mapping of upstream servers with proxy_pass directive?

Solution 1:

you need to describe your URI pattern in regular expression and use it in your location to capture the parts of it that you can use in the rewrite or proxy_pass target. e.g.:

location ~ ^/url_(.).*$ {
  #this will capture your /url_a or /url_b URI's 
  #and will store the "a" or "b" into $1 variable
  #which you can use to proxy the request to a specific server
  proxy_pass http://$1.$upstreams$uri;
  #the above will result in a.<upstreams>/url_a for your example.
  #don't forget the resolver configuration for domain names.
}

hope it helps

Solution 2:

Depending on what exactly is it that you want, there are a few directives that come to mind:

  • http://nginx.org/r/upstream
  • http://nginx.org/r/map
  • http://nginx.org/r/geo

E.g., if you basically just want to have nginx proxy everything to your various upstream servers that aren't fully aware of their internet names, and have a mapping between internal and external names, then something like this should do it:

map $host $host_upstream_mapped {
    hostnames;

    test.example.su  test_iis.internal:8070;
    example.com  bleeding_edge.internal:9999;

    default  localhost:8080;
}
server {
    listen [::]:80;
    location / {
        proxy_pass http://$host_upstream_mapped$request_uri;
    }
}

P.S. Note that it's important to use $request_uri in this context (and not just $uri, because otherwise you'll be leaving $args behind), or, alternatively, if you're using rewrite directives as well, then $uri$is_args$args is also a good option (note that the two are not equivalent).