nginx proxypass with multiple locations - nginx

I try to setup nginx such that it proxies requests to multiple locations. E.g. /location1 and /location2 should both be proxied to http://localhost:8080. I just can't figure out how to configure this without using multiple location blocks. I already tried:
location /(location1|location2) {
proxy_pass http://localhost:8080/
}
which will only give 404s. And I've also tried:
location ~ /(location1|location2) {
proxy_pass http://localhost:8080/
}
Which will thrown an error that regular expressions are not allowed with proxy pass.
Is it possible to configure this proxy without having to create multiple location blocks?

Apparently is missing a slash and a ';'. Try this:
location ~ (/location1|/location2) {
proxy_pass http://localhost:8080;
}

Related

Replicate proxy_pass location behavior with variables

So usually when creating a nginx location it would look something like this:
location /foo/ {
proxy_pass http://example.com/;
}
With this setup, requests to /foo/bar are forwarded to http://example.com/bar which is the intended behavior.
However when trying to prevent caching of the domain name example.com or when trying to prevent nginx from crashing if the upstream host is unavailable at startup the only solution seems to be to not use the target directly in the proxy_pass directive, but to instead create a variable containing the target like this:
location /foo/ {
set $targetUri http://example.com/;
proxy_pass $targetUri;
}
But this totally changes the setup. As soon as proxy_pass contains a variable, it no longer appends anything to the target uri, as the nginx docs describe:
When variables are used in proxy_pass [...]. In this case, if URI is specified in the directive, it is passed to the server as is, replacing the original request URI.
So requests to /foo/bar are simply forwarded to http://example.com/.
When bringing $request_uri into the mix, more than what we want is appended:
location /foo/ {
set $targetUri http://example.com$request_uri;
proxy_pass $targetUri;
}
Requests to /foo/bar are now forwarded to http://example.com/foo/bar.
The only workaround I have found is to resort to regex patterns for the location:
location ~ ^/foo/(.*)$ {
set $targetUri http://example.com/$1$is_args$args;
proxy_pass $targetUri;
}
Is there any way to replicate the behavior of proxy_pass when using variables without having to regex-match the location? The reason I want to avoid regex is because the location path is based on a user input from which the location block is generated.
Remove the trailing / from your $targetUri variable so that proxy_pass does not have the "optional URI" part in its value. Then use rewrite...break to duplicate the original behaviour.
For example:
location /foo/ {
set $targetUri http://example.com;
rewrite ^/foo(.*)$ $1 break;
proxy_pass $targetUri;
}

Nginx How do i route to reverse proxy by location

Currently i'm using nginx server and using nodejs server as reverse proxy.
I want to make the nginx server proxy_pass different server by location.
So, lets say my domain is subdomain.domain.com.
When loading subdomain.domain.com/, this should serve static files.
When loading subdomain.domain.com/example1/req1/req2, this should route to 127.0.0.1:3000/req1/req2.
When loading subdomain.domain.com/example2/req1/req2, this should route to 127.0.0.1:8080/req1/req2.
But my configuration routes subdomain.domain.com/example1/req1/req2 to 127.0.0.1:3000/example1/req1/req2 resulting error. (nodejs returns Cannot GET /example1)
How should I write this nginx conf file properly?
Try use rewrite directive in location block.
Something like:
location /example1/ {
rewrite ^/example1/(.*)$ /$1 break;
proxy_pass http://xxxxxx;
}
You can check documents related to rewrite module at http://nginx.org/en/docs/http/ngx_http_rewrite_module.html
You need to add below code snippet to your nginx.conf.
server subdomain.domain.com;
location / {
rewrite ^/example1/(.*)$ /$1 break;
proxy_pass http://127.0.0.1:3000;
}
}

Nginx rewrite with proxy_pass

I recently have a requirement in Nginx to rewrite a URL and then forward this onto to another backend server to a dynamic proxy pass address. I've tried a few things but have not had much luck at the moment. For example, this is the kind of setup I have in my nginx.conf file:
server {
listen 443;
server_name scheduler.domain-name;
rewrite ^scheduler(.*)/(.*)/(.*) $2$1$3; # scheduler.domain.local/changepass/report?target=service
...
location / {
proxy_pass $to-rewrite-address:9443; # changepass.domain.local/report?target=service
...
}
Essentially, I just need to use a re-written URL variable to forward the request on a different port but can't seen to get this to work.
I've done quite a bit of searching but haven't found the solution to this as of yet, though I understand that the DNS resolver has to be set when using a proxy pass variable (Dynamic proxy_pass to $var with nginx 1.0).
Grateful if anyone could advise on how the above could be achieved, many thanks.
Assuming your endpoint would always be specified as the first part of your URI, here is an example of configuration that should work:
server {
listen 443;
server_name scheduler.domain-name;
resolver <your resolver for domain.local>;
...
location ~ ^/(?<endpoint>changepass|endpoint2|endpoint3|...)(?<route>/.*) {
proxy_pass http://$endpoint.domain.local:9443$route;
}
}
I'm using named capturing groups here for a better readibility, this location block is equal to
location ~ ^/(changepass|endpoint2|endpoint3|...)(/.*) {
proxy_pass http://$1.domain.local:9443$2;
}
I'm not sure if query arguments would be preserved with such a construction, if they won't, change
proxy_pass http://$endpoint.domain.local:9443$route;
to
proxy_pass http://$endpoint.domain.local:9443$route$is_args$args;

Proxy_Pass using Nginx on windows

i am trying to use nginx for my hosted website on Azure using location. but even if i configure Nginx for google, i get a 404.
location /master
{
proxy_pass http://www.google.com;
}
See this thread for url details on proxy_pass
Nginx proxy_pass only works partially
Your config
location /master
{
proxy_pass http://www.google.com;
}
Send /master also as the part of the url. Which means you are trying to go to http://www.google.com/master. So this won't work as it is a 404. But if you add trailing / to both your locations
location /master/
{
proxy_pass http://www.google.com/;
}
The /master will not be sent as the request url. Also this would just work for a brief moment as you will get a 301 to https://www.google.com. So better is to use proxy_pass https://www.google.com/;

NGINX Location troubles

I have django and flask applications running on the same machine through different ports:
Django runs on server:8088
Flask runs on server:666
In NGINX.conf I have the following code:
location / {
proxy_pass http://127.0.0.1:8088;
}
location ^/server2 {
proxy_pass http://127.0.0.1:666;
}
Django has been running for over a year successfully with this set up, where as flask is a new addition. Any time I try to access one of the Flask urls I either get a "this url does not exist on this server" error, or on occasion a 500 error (when i've been fiddling).
If I write location information for a specific flask url like this:
location /server2/splash {
proxy_pass http://127.0.0.1:666/splash;
}
It works, but I obviously don't want to write individual location information for each and every URL in the flask application.
I've gone through many of the existing Nginx location posts on stackoverflow but I've not been able to get it working. Any ideas?
Thanks!
EDIT
this is an example of what I'm trying to achieve, but rather than an individual mapping for each URL, I want a single mapping that covers all URLs:
location /server2{
proxy_pass http://127.0.0.1:666/splash;
}
location /server2/split {
proxy_pass http://127.0.0.1:666/split;
}
location /server2/export {
proxy_pass http://127.0.0.1:666/export;
}
location /server2/import {
proxy_pass http://127.0.0.1:666/import;
}
Why do you use the ^ sign? Just remove it I think it will work:
location /server2 {
proxy_pass http://127.0.0.1:666;
}
Note that when you use location /server2 the server2 is still being passed to your flask application.
In this case Nginx is doing the following:
server.com/server2 => http://127.0.0.1:666/server2
server.com/server2/splash => http://127.0.0.1:666/server2/splash
In this case location is not doing a rewrite. Always check /var/log/nginx (or wherever your logs are located) to check the requests done by the browser and what Nginx looks for after the rules for your site are processed.
What you probably want is to set an upstream directive:
upstream flask_server {
server 127.0.0.1:666;
}
server {
...
location /server2 {
proxy_pass http://flask_server;
}
}

Resources