Nous avons plusieurs applications Rails dans le domaine commun de Docker et nous utilisons nginx pour diriger les demandes vers des applications spécifiques.
our_dev_server.com/foo # proxies to foo app
our_dev_server.com/bar # proxies to bar
La configuration ressemble à ceci:
upstream foo {
server foo:3000;
}
upstream bar {
server bar:3000;
}
# and about 10 more...
server {
listen *:80 default_server;
server_name our_dev_server.com;
location /foo {
# this is specific to asset management in Rails dev
rewrite ^/foo/assets(/.*)$ /assets/$1 break;
rewrite ^/foo(/.*)$ /foo/$1 break;
proxy_pass http://foo;
}
location /bar {
rewrite ^/bar/assets(/.*)$ /assets/$1 break;
rewrite ^/bar(/.*)$ /bar/$1 break;
proxy_pass http://bar;
}
# and about 10 more...
}
Si l'une de ces applications n'est pas lancée, nginx échoue et s'arrête:
Host not found in upstream "bar:3000" in /etc/nginx/conf.d/nginx.conf:6
Nous n’avons pas besoin qu’ils soient tous actifs, mais nginx échoue sinon . Comment faire pour que nginx ignore les flux amont échoués?
Si vous pouvez utiliser une adresse IP statique, utilisez-la simplement, elle démarrera et renverra simplement les 503
si elle ne répond pas.
Utilisez la directive resolver
pour pointer sur un problème susceptible de résoudre l'hôte, qu'il soit opérationnel ou non.
Résolvez-le au niveau location
, si vous ne pouvez pas faire ce qui précède (cela permettra à Nginx de démarrer/exécuter) :
location /foo {
resolver 127.0.0.1 valid=30s;
# or some other DNS (you company/internal DNS server)
#resolver 8.8.8.8 valid=30s;
set $upstream_foo foo;
proxy_pass http://$upstream_foo:80;
}
location /bar {
resolver 127.0.0.1 valid=30s;
# or some other DNS (you company/internal DNS server)
#resolver 8.8.8.8 valid=30s;
set $upstream_bar foo;
proxy_pass http://$upstream_bar:80;
}
Le principal avantage de upstream
est de définir un groupe de serveurs pouvant écouter sur différents ports, de configurer l'équilibrage de charge et le basculement entre eux.
Dans votre cas, vous êtes définissez uniquement 1 serveur principal par amont, donc il doit être actif.
Au lieu de cela, utilisez des variables pour votre proxy_pass
(es) et n'oubliez pas de gérer les erreurs possibles (404, 503) que vous pourriez obtenir lorsqu'un serveur cible est en panne.
Pour moi, l'option 3 de la réponse de @ Justin/@ duskwuff a résolu le problème, mais je devais modifier l'IP du résolveur en 127.0.0.11 (serveur DNS de Docker):
location /foo {
resolver 127.0.0.11 valid=30s;
set $upstream_foo foo;
proxy_pass http://$upstream_foo:80;
}
location /bar {
resolver 127.0.0.11 valid=30s;
set $upstream_bar foo;
proxy_pass http://$upstream_bar:80;
}
Toutefois, comme @ Justin/@ duskwuff l’a mentionné, vous pouvez utiliser n’importe quel autre serveur DNS externe.