Nginx: dynamic proxy_pass

I want to use nginx for a dynamic proxy. Here are the rules:

/os-abc/... to http://abc.a.domain.com:1234/...
/os-xxx/... to http://xxx.a.domain.com:1234/...
/os-yyy/... to http://yyy.a.domain.com:1234/...
...

So I write a proxy rule in nginx.conf.

location ~ ^/os-(.*)/ {
    proxy_pass http://$1.a.domain.com:1234/;

    add_header Cache-Control 'public, max-age=99999999999, immutable';
    proxy_set_header Host $host;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}

But it does NOT work (get 502). nginx version: nginx/1.28.2

My Question

  1. How could I see what http://$1.a.domain.com:1234/ becomes?

  2. How to let it work?

  3. Why is this simple requirement so hard to implement?

Progress

I add resolver directive to the conf file. But the error log shows: hdd1 could not be resolved (3: Host not found). It seems nginx force to resolve $1 instead of β€œ$1.a.domain.com”.

Get it work. The correct conf:

location ~ ^/os-(?<subdomain>[^/]+)(?<path>/.*)?$ {
        proxy_pass http://$subdomain.abc.com:8060$path$is_args$args;

        proxy_set_header Host $subdomain.abc.com;
}

Some points:

  1. Wrong regex. Use [^/]+ instead of .*.
  2. Wrone Host. Use $subdomain.abc.com instead of $host.
  3. Must concatenate path manually when using regex. Use http://$subdomain.abc.com:8060$path$is_args$args instead of http://$1.a.domain.com:1234/.
  4. Can’t see the backend url. Very hard to debug.

Have to say

The rule of conf is TOO tricky.

1 Like

Thank you for sharing your solve @jim-king-2000 !

It took me 2 days to debug it. It would be much easier if I could see the proxyed url. Hope nginx would add it to the log. Or new users would repeat my failure.

1 Like

We can look into this. Thank you for highlighting.

1 Like

This topic was automatically closed 2 days after the last reply. New replies are no longer allowed.