8

Working on a new version of an existing web app, I need nginx to forward root (/) and multiple specific URI to be forwarded to the v2 infrastructure (with proxy_pass) while not specified URI must be forwarded to v1.

location = /specific_uri1
        proxy_pass http://v2.webapp.com;
        proxy_set_header Host       v2-test.webapp.com;
        add_header       X-version  v2;
        add_header       X-node     $hostname;
}

location = /specific_uri2
        proxy_pass http://v2.webapp.com;
        proxy_set_header Host          v2-test.webapp.com;
        add_header       X-version     v2;
        add_header       X-node        $hostname;
}

location / {
        proxy_pass http://v2.webapp.com;
        proxy_set_header Host          v2-test.webapp.com;
        add_header       X-version     v2;
        add_header       X-node        $hostname;
}

location /(.*)$ {
        proxy_pass http://v1.webapp.com;        
        proxy_set_header   Host         v1-test.webapp.com;
        add_header         X-version    v1;
        add_header         X-node       $hostname;
}

The last location directive is never matched so everything not declared still fall to the v2 web app. I surely have a misunderstanding of the way nginx process the directives.

I have tested many configurations none of them working for my case.

Thank you.

UPDATE:

I have updated my configuration with the following block :

location ~* /specific_uri1/ {
        proxy_pass http://v2.webapp.com:8008;
        proxy_set_header Host       v2-test.webapp.com;
        add_header              X-version     v2;
        add_header              X-node   $hostname;
}


location = / {
        proxy_pass http://v2.webapp.com:8008;
        proxy_set_header        Host    v2-test.webapp.com;
        add_header              X-version     v2;
        add_header              X-node   $hostname;
}

location / {
        proxy_set_header        Host    v1.webapp.com;
        proxy_pass      http://v1-test.webapp.com;
        add_header      X-version     v1;
        add_header      X-node   $hostname;
}

All requested URI are forwarded to the correct version, but, assets from /specific_uri1 and from / (root) are fetch from v1 (instead of v2), resulting http 404 errors. My assets are loaded from URI like /js/main.js?v=0.9.0-sprint14 so I guess the last location block is match for them. Since both versions of my app use the same folder tree I can't specify /js or /img location. What would be the right way to handle this ?

cyrilv
  • 305
  • 2
  • 3
  • 11
  • With Richard Smith's config root and specific_uri1 are fetch from v2 but assets from v1. Not specified uri are correctly forwarded to v1. I'm pretty confused. – cyrilv Apr 21 '17 at 14:49

1 Answers1

7

location / matches any location - if you want to match only /, you should use location = /. See this document for details.

Also, your regular expression location is missing the ~ or ~* operator. But the last location block in your question should be location /.

You might simplify the configuration by using a single regular expression:

location ~* ^/(|specific_uri1|specific_uri2)$ {
    proxy_pass http://v2.webapp.com;
    proxy_set_header Host          v2-test.webapp.com;
    add_header       X-version     v2;
    add_header       X-node        $hostname;
}

location / {
    proxy_pass http://v1.webapp.com;        
    proxy_set_header   Host         v1-test.webapp.com;
    add_header         X-version    v1;
    add_header         X-node       $hostname;
}
Richard Smith
  • 11,859
  • 2
  • 18
  • 26