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
upstream
bloque 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.sh
script que lee variables de entorno y agregaupstream
entradas 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á
503
la si no responde.Utilice la
resolver
directiva para señalar algo que pueda resolver el host, independientemente de si está activo o no.Resuélvalo en el
location
nivel, 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
upstream
es 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://foo
yproxy_pass $variable
mantengo el foo "upstream" (para mantener las ventajas que mencionaste), entonces todavía estaré abordando el problema mencionado por OP.set $variable foo
yproxy_pass http://$variable
Tuve el mismo problema de "Host no encontrado" porque parte de mi host se estaba mapeando usando en
$uri
lugar de$request_uri
:Y cuando la solicitud cambió a la subquest de autenticación,
$uri
perdió su valor inicial. Cambiar el mapeo para usar en$request_uri
lugar de$uri
resolver mi problema:fuente
No puede usar la
--link
opció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:80
opción, segundo contenedor con-p 280:80
opción.Ejecute nginx y configure estas direcciones para el proxy:
fuente