Nginx – Use upstream servers based on request method with NGINX

nginxPROXY

i'm using nginx's upstream directive to do some load balancing. But i want to handle the POST requests and the requests for /upload directory by my main server.

how can i tell nginx "dont proxy pass if the request method is POST or the url contains /admin or /upload"?

my current upstreams looks like this:

upstream appcluster {
                ip_hash;
                server 10.200.0.194:9000; 
       }

        upstream admincluster {
                ip_hash;
                server unix:/tmp/php5-fpm.sock;

        }

and my sites-enabled/default

location ~ \.php(.*)$ {
                try_files $uri =404;

                fastcgi_split_path_info ^(.+\.php)(/.+)$;
                # NOTE: You should have "cgi.fix_pathinfo = 0;" in php.ini


                #fastcgi_pass 127.0.0.1:9000;
                #fastcgi_pass unix:/tmp/php5-fpm.sock;
                fastcgi_index index.php;

                fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
                fastcgi_param APPLICATION_ENV production;

                include fastcgi_params;
                fastcgi_pass appcluster;


        }

Best Answer

You should be able to add something like this in front of the other location block:

location /upload {
  break;
}

location /admin {
  break;
}

if ($request_method = POST ) {
  break;
}

Update:

nginx first searches for the most specific location given by literal strings regardless of the listed order. In the configuration above the only literal location is “/” and since it matches any request it will be used as a last resort. Then nginx checks locations given by regular expression in the order listed in the configuration file. The first matching expression stops the search and nginx will use this location. If no regular expression matches a request, then nginx uses the most specific literal location found earlier.

So, the /upload and /admin location blocks are literals and are processed after the regex you're using for the proxy.

Try "location ~ ^/admin" and so on.