62

I'm trying to get these 2 location directives working in Nginx but I'm getting some errors back when booting Nginx.

   location ~ ^/smx/(test|production) {
        proxy_pass   http://localhost:8181/cxf;
    }

    location ~ ^/es/(test|production) {
        proxy_pass   http://localhost:9200/;
    }

This is the error I'm receiving:

nginx: [emerg] "proxy_pass" cannot have URI part in location given by regular expression, or inside named location, or inside "if" statement, or inside "limit_except" block

Does it sounds familiar to anyone? What I'm I missing here?

HopelessN00b
  • 53,385
  • 32
  • 133
  • 208
Niels
  • 771
  • 2
  • 8
  • 8

2 Answers2

68

A small addition to the great answer from Xaviar:

If you happen to be not so well acquainted with nginx, there's an important difference between adding the slash to the end of the proxy_pass directive.

The following does not work:

location ~* ^/dir/ {
  rewrite ^/dir/(.*) /$1 break;
  proxy_pass http://backend/;

but this one does:

location ~* ^/dir/ {
  rewrite ^/dir/(.*) /$1 break;
  proxy_pass http://backend;

The difference being the / at the end of the proxy_pass directive.

mark
  • 1,516
  • 4
  • 21
  • 33
31

It tells you that the URI in the proxy pass directive can't be used in a regex location. This is because nginx can't replace the part of the URI matching the regex in the location block with the one passed in the proxy_pass directive a generic way.

Simply imagine your location regex is /foo/(.*)/bar, and you specify proxy_pass http://server/test, nginx would have to map your location regex to another one on an upper level because you don't want to end with /foo/test/bar/something but with /test/something. So that's not possible natively.

So for this part using the following should work :

server {

   [ ... ]

    location ~ ^/smx/(test|production) {
        rewrite ^/smx/(?:test|production)/(.*)$ /cxf/$1 break;
        proxy_pass http://localhost:8181;
    }

    location ~ ^/es/(test|production) {
        rewrite ^/es/(?:test|production)/(.*)$ /$1 break;
        proxy_pass http://localhost:9200;
    }

}

However, it won't be possible to rewrite redirects to match the location block URI pattern because it rewrites the current URI being processed, making it impossible to change the Location header based on the initial request before rewrite.

mikemaccana
  • 3,070
  • 5
  • 24
  • 29
Xavier Lucas
  • 12,815
  • 2
  • 44
  • 50