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:
- 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.
- 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.