Nginx proxy_pass failover to multiple upstream servers - nginx

I'm having a hard time finding a solution for nginx proxy_pass failover setup.
I need to proxy certain locations to backend server URL's -
location /Data {
proxy_pass https://backend1.example.com/site1-url;
proxy_set_header X_HOST $host;
}
location /Photos {
proxy_pass https://backend1.example.com/site2-url;
proxy_set_header X_HOST $host;
}
It works as expected, but I need nginx to failover to another server. So the obvious thing would be to use upstream:
upstream servers {
server backend1.example.com;
server backend2.example.com backup;
{
location /Data {
proxy_pass https://servers/site1-url;
proxy_set_header X_HOST $host;
}
location /Photos {
proxy_pass https://servers/site2-url;
proxy_set_header X_HOST $host;
}
..., but this doesn't work. Nginx doesn't understand that the proxy_pass contains upstream.
Is there an elegant way to do this?

Use proxy_pass https://servers and use a rewrite to go to site1-url and site2-url:
location /Data {
rewrite ^ /site1-url/$request_uri? break;
proxy_pass https://servers;
proxy_set_header X_HOST $host;
}
location /Photos {
rewrite ^ /site2-url/$request_uri? break;
proxy_pass https://servers;
proxy_set_header X_HOST $host;
}
WARNING: I've not tested this configuration.

Related

Ngixn rewrite and reverse proxy to docker container

I am running 3 services using docker compose on 3 ports: svc1:8081, svc2:8082, and svc3:8083 respectively. I have nginx installed on my host machine (not as a docker container), I want to reverse proxy all the requests to appropriate services so I am rewriting the url inside the nginx location block and performing a reverse proxy.
I am unable to get the results as something the files are not loading (mainly the static file to docker container)
My nginx config is as follows:
server {
listen 80;
server_name - ;
location /svc1/ {
rewrite ^/svc1(.*)$ $1 break;
proxy_pass http://localhost:8081;
}
location /svc2/ {
rewrite ^/svc2(.*)$ $1 break;
proxy_pass http://localhost:8082;
}
location /svc3/ {
rewrite ^/svc3(.*)$ $1 break;
proxy_pass http://localhost:8083;
}
}
I would be thankful if anyone can point if I am doing any wrong. Thanks in advance for your help.
Try this:
server {
listen 80;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Referer $http_referer;
# Additionally those headers if websocket/reload is used:
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
location /svc1/ {
proxy_pass http://localhost:8081/;
}
location /svc2/ {
proxy_pass http://localhost:8082/;
}
location /svc3/ {
proxy_pass http://localhost:8083/;
}
}
Don't forget to restart nginx after changing conf!

nginx redirect different roots to different ports

After hours of checking documents and stackoverflow, I still cannot figure out how to do this.
this is my nginx.conf:
http {
upstream backend {
least_conn;
server 192.168.77.81:8078 weight=4;
server 192.168.77.231:8078 weight=7 max_fails=1 fail_timeout=1s;
}
upstream static_backend {
server 192.168.77.81:8079;
}
server {
listen 8068;
access_log off;
error_log off;
location / {
proxy_pass http://backend;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
location /static/ {
proxy_pass http://192.168.77.81:8079;
}
}
}
events {}
I want to redirect all the http://192.168.77.81:8068/static to http://192.168.77.81:8079/static
but it all results in either 301 Moved Permanently or http://192.168.77.81:8078/static
which drive me crazy
I also have tried alias and root, and they don't work as well
any advice would be very appreciated!
simply just do proxy_pass ~ /static
this "~" took me hours...

How to rewrite or proxy url in nginx?

I am new in nginx. I want to rewrite
feature-1234.mydomain.com/xyz?foo=bar
to
docker-feature-1234:9000/xyz?foo=bar
with request parameters.
I use official nginx docker image. How should be my nginx.conf file?
EDIT: 'feature-1234' is a variable so:
feature-5678.mydomain.com
should serve as
docker-feature-5678:9000
By combining answers, i found the solution.
https://serverfault.com/questions/388552/nginx-sub-domain-proxy-pass
Docker Network Nginx Resolver
nginx: [emerg] "server" directive is not allowed here
nginx.conf:
events {
}
http {
server {
listen 80;
server_name ~(.*).test.go;
location / {
if ($host ~* ^([a-zA-Z0-9-]+)\.test\.go$) {
set $proxyhost docker-$1:9000;
}
resolver 127.0.0.11 ipv6=off;
proxy_pass http://$proxyhost;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $host;
}
}
}
Thanks

How to configure Nginx to try two upstreams before 404ing?

Given an Nginx configuration roughly like this:
upstream A {
server aa:8080;
}
upstream B {
server bb:8080;
}
server {
listen 80;
location #backendA {
proxy_pass http://A/;
}
location #backendB {
proxy_pass http://B/;
}
location / {
# This doesn't work. :)
try_files #backendA #backendB =404;
}
}
Basically, I would like Nginx to try upstream A, and if A returns a 404, then try upstream B instead, and failing that, return a 404 to the client. try_files does this for filesystem locations, then can fall back to a named location, but it doesn't work for multiple named locations. Is there something that will work?
Background: I have a Django web application (upstream A) and an Apache/Wordpress instance (upstream B) that I would like to coexist in the same URL namespace for simpler Wordpress URLs: mysite.com/hello-world/ instead of mysite.com/blog/hello-world/.
I could duplicate my Django URLs in the Nginx locations and use wordpress as a catch-all:
location /something-django-handles/ {
proxy_pass http://A/;
}
location /something-else-django-handles/ {
proxy_pass http://A/;
}
location / {
proxy_pass http://B/;
}
But this violates the DRY principle, so I'd like to avoid it if possible. :) Is there a solution?
After further googling, I came upon this solution:
location / {
# Send 404s to B
error_page 404 = #backendB;
proxy_intercept_errors on;
log_not_found off;
# Try the proxy like normal
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_pass http://A;
}
location #backendB {
# If A didn't work, let's try B.
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_pass http://B;
# Any 404s here are handled normally.
}

how to reverse proxy via nginx a specific url?

I have a server running at http://localhost:8080 i want a specific url of this server to be proxied by nginx.
For example, i only want http://localhost:8080/test/(.*) to be reverse proxied to http://localhost/test/(.*).
I'm proxing another server to http://localhost/.
What about just a simple location block?
server {
# ... other stuff
location /test/ {
try_files $uri #testproxy;
}
location #testproxy {
proxy_pass http://127.0.0.1:8080;
proxy_set_header X-Forwarded-Host $server_name;
proxy_set_header X-Real-IP $remote_addr;
# all your params
}
}
I made it somehow this way and it worked. Thanks for your comment anyway. :)
server {
listen 80;
# ... other stuff
upstream backend1 {
server 127.0.0.1:8080;
}
location /test/ {
proxy_pass_header Server;
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Scheme $scheme;
proxy_pass http://backend1/test/;
}
}

Resources