nginx does not automatically pick up dns changes in swarm
Thanks to @Moema's pointer I've come up with a solution to this. The default configuration of lets-nginx needs to be tweaked as follows to make nginx pick up IP changes:
resolver 127.0.0.11 ipv6=off valid=10s; set $upstream http://${UPSTREAM}; proxy_pass $upstream;
This uses docker swarm's resolver with a TTL and sets a variable, forcing nginx to refresh name lookups in the swarm.
Remember that when you use set
you need to generate the entire URL by yourself.
I was using nginx in a compose to proxy a zuul gateway :
location /api/v1/ { proxy_set_header X-Forwarded-Host $host:$server_port; proxy_pass http://rs-gateway:9030/api/v1/; } location /zuul/api/v1/ { proxy_set_header X-Forwarded-Host $host:$server_port; proxy_pass http://rs-gateway:9030/zuul/api/v1/; }
Now with Swarm it looks like that :
location ~ ^(/zuul)?/api/v1/(.*)$ { set $upstream http://rs-gateway:9030$1/api/v1/$2$is_args$args; proxy_pass $upstream; # Set headers proxy_set_header X-Forwarded-Host $host:$server_port; proxy_set_header Host $host; proxy_set_header X-Forwarded-For $remote_addr; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection $http_connection; }
Regex are good but don't forget to insert GET params into the generated URL by yourself.