Home > Enterprise >  Can we set up Nginx upstream with different paths?
Can we set up Nginx upstream with different paths?

Time:11-20

Im setting up docker dev environment that can run several app servers in one container. I also have real servers running in our test environment. Lets say I have 10 servers in the container but I dont want all to run at the same time. I want to set up nginx to route traffic for each app based on if the local server is running (sort of like a circuit breaker pattern). The below config is almost what I want but the issue is I need it to map to a different path if it uses the 'backup' server. I should also mention I have a /etc/host file config to hijack the requests to test.mycompany.com and route them to local nginx 127.0.0.1.

upstream myapp{
  server 127.0.0.1:8082;
  server 172.26.1.1:80 backup;
}

server {
  listen 80;

  location /approot/ {
    proxy_pass http://myapp/;
  }
}

As an example take this URL which runs from inside the docker host. host file config ensures it routes through nginx in the container:

If the server is up and running in the docker container nginx should route the request to:

If the server is down it should go to the backup server but with different path:

its basically working except I cant figure out how to add /approot/ back in for the backup server.

CodePudding user response:

I guess the below works and I dont really see much of a performance hit (its dev environment anyway so few milliseconds aren't going to kill me). Would still like a cleaner solution if there is one though. Basically if the server 127.0.0.1:8082 is not running it will send to 127.0.0.1:8085 which is another nginx reverse proxy which will route it to our test server. Luckily our test.mycompany.com is a load balanced url and we can also directly call test01/test02 directly, otherwise my host file would just route this right back to localhost in an infinite loop.

upstream myapp{
  server 127.0.0.1:8082;
  server 127.0.0.1:8085 backup;
}

server {
  listen 80;

  location /approot/ {
    proxy_pass http://myapp/;
  }
}


#add back in the root context
server {
  listen 8085;

  location / {
    proxy_pass http://test01.mycompany.com/approot/;
  }
}

/etc/hosts

127.0.0.1 test.mycompany.com

CodePudding user response:

I ended up going with the below since it is more extensible. Nice thing is it will sort of still load balance between the backups in a round about way. if a request comes in on port 80 it will try to proxy to port 8180 which then strips the /approot/ context and proxies it again to port 8082. If that errors it will automatically try the backups which are also pointing to nginx reverse proxies.

upstream myhosts{
  server 127.0.0.1:8180;
  server 127.0.0.1:8181 backup;
  server 127.0.0.1:8182 backup;
}

server {
  listen 80;

  location /approot/ {
    proxy_pass http://myhosts/approot/;
    proxy_next_upstream error timeout http_502;
  }
}


server {
  listen 8180;

  location /approot/ {
    proxy_pass http://127.0.0.1:8082/;
  }
}

server {
  listen 8181;

  location /approot/ {
    proxy_pass http://test01.mycompany.com/approot/;
  }
}

server {
  listen 8182;

  location /approot/ {
    proxy_pass http://test01.mycompany.com/approot/;
  }
}

/etc/hosts

127.0.0.1 test.mycompany.com

Few notes:

  1. nginx listens on port 80 by default and I had to disable this in nginx.conf (comment out the line include available-sites). This caused me hours of confusion since it looked like none of my configuration was having any effect.
  2. if you have an upstream that is also a reverse proxy it will return a 502 (bad gateway) response. nginx will not go to the next upstream by default in this case because it did infact establish a connection to something running on port 8180. Hence I had to add proxy_next_upstream http_502 in the first proxy for it to go to the backups.
  • Related