Tenemos varias aplicaciones de rieles bajo un dominio común en Docker, y usamos nginx para dirigir solicitudes a aplicaciones específicas.
our_dev_server.com/foo # proxies to foo app
our_dev_server.com/bar # proxies to bar
La configuración se ve así:
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 una de estas aplicaciones no se inicia, nginx falla y se detiene:
host not found in upstream "bar:3000" in /etc/nginx/conf.d/nginx.conf:6
No los necesitamos todos para estar activos, pero nginx falla de lo contrario. ¿Cómo hacer que nginx ignore los upstreams fallidos?
nginx
url-rewriting
proxypass
Morozov
fuente
fuente

upstreambloque no se resuelve, en tiempo de ejecución, Nginx saldrá con el error anterior ...resolver( nginx.org/en/docs/http/ngx_http_core_module.html#resolver ) en su caso?proxy.shscript que lee variables de entorno y agregaupstreamentradas dinámicamente para cada una, luego inicia Nginx. Esto funciona muy bien porque cuando ejecutamos nuestro contenedor de proxy podemos pasar los flujos ascendentes necesarios en tiempo de ejecución. Puede hacer algo similar para habilitar / deshabilitar ciertas corrientes ascendentes en el lanzamiento (o como mi configuración, simplemente agregue las necesarias en tiempo de ejecución)Respuestas:
Si puede usar una IP estática, utilícela, se iniciará y devolverá
503la si no responde.Utilice la
resolverdirectiva para señalar algo que pueda resolver el host, independientemente de si está activo o no.Resuélvalo en el
locationnivel, si no puede hacer lo anterior (esto permitirá que Nginx se inicie / ejecute) :fuente
location ~ ^/foo/(.*)$ { proxy_pass http://foo/$1; }Para mí, la opción 3 de la respuesta de @ Justin / @ Sunsetwuff resolvió el problema, pero tuve que cambiar la IP del resolutor a 127.0.0.11 (servidor DNS de Docker):
Pero como mencionó @ Justin / @ anochecerwuff, podría usar cualquier otro servidor DNS externo.
fuente
La principal ventaja de usar
upstreames definir un grupo de servidores que pueden escuchar en diferentes puertos y configurar el equilibrio de carga y la conmutación por error entre ellos .En su caso, solo está definiendo 1 servidor primario por flujo ascendente, por lo que debe estar activo .
En su lugar, use variables para su
proxy_pass(s) y recuerde manejar los posibles errores (404, 503) que puede obtener cuando un servidor de destino no funciona.fuente
set $variable http://fooyproxy_pass $variablemantengo el foo "upstream" (para mantener las ventajas que mencionaste), entonces todavía estaré abordando el problema mencionado por OP.set $variable fooyproxy_pass http://$variableTuve el mismo problema de "Host no encontrado" porque parte de mi host se estaba mapeando usando en
$urilugar de$request_uri:Y cuando la solicitud cambió a la subquest de autenticación,
$uriperdió su valor inicial. Cambiar el mapeo para usar en$request_urilugar de$uriresolver mi problema:fuente
No puede usar la
--linkopción, en su lugar puede usar la asignación de puertos y vincular nginx a la dirección del host.Ejemplo: Ejecute su primer contenedor docker con
-p 180:80opción, segundo contenedor con-p 280:80opción.Ejecute nginx y configure estas direcciones para el proxy:
fuente