Nginx chooses a random location block

nginxreverse-proxy

I would like to redirect requests to different servers depending on path, therefore I am using the following http block in the Nginx configuration:

http {
  include  /etc/nginx/mime.types;
  default_type  application/octet-stream;
  index index.html index.htm;

  server {
    access_log  /var/log/nginx/staging.access.log main buffer=32k;
    error_log   /var/log/nginx/staging.error.log error;
    listen      80;
    root        /dev/null;

    location / {
      proxy_pass        http://core:80;  # returns "Core Service"
    }

    location /page/ {
      rewrite ^/page(/.*)$ $1 break;
      proxy_pass        http://page:80;  # returns "Page Service"
    }

    location /auth/ {
      rewrite ^/auth(/.*)$ $1 break;
      proxy_pass        http://auth:80;  # returns "Auth Service"
    }
  }
}

As far as I understand the Nginx documentation, Nginx should use the best matching location block, therefore I would expect that curl http://hostname/ should return "Core Service", curl http://hostname/auth "Auth Service" and curl http://hostname/ "Page Service". Nginx however uses a random location block:

$ curl  http://hostname/
Core Service
$ curl  http://hostname/
Auth Service
$ curl  http://hostname/
Page Service
$ curl  -L http://hostname/page
Auth Service
$ curl  -L http://hostname/page
Auth Service
$ curl  -L http://hostname/page
Core Service

What is wrong with my configuration?

Best Answer

You have added trailing / character at the end of your each match, try to edit as follow:

location /page {
  rewrite ^/page(/.*)$ $1 break;
  proxy_pass        http://page:80;  # returns "Page Service"
}

location /auth {
  rewrite ^/auth(/.*)$ $1 break;
  proxy_pass        http://auth:80;  # returns "Auth Service"
}