skip to Main Content

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.

2

Answers


  1. Chosen as BEST ANSWER

    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
    

  2. 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.
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search