Temos vários aplicativos rails sob domínio comum no Docker e usamos o nginx para direcionar solicitações a aplicativos específicos.
our_dev_server.com/foo # proxies to foo app
our_dev_server.com/bar # proxies to bar
A configuração é semelhante a esta:
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...
}
Se um desses aplicativos não for iniciado, o nginx falhará e para:
host not found in upstream "bar:3000" in /etc/nginx/conf.d/nginx.conf:6
Não precisamos que todos estejam ativados, mas o nginx falha de outra forma. Como fazer o nginx ignorar upstreams com falha?
nginx
url-rewriting
proxypass
Morozov
fonte
fonte
upstream
bloco não resolver, em tempo de execução, então o Nginx sairá com o erro acima ...resolver
( nginx.org/en/docs/http/ngx_http_core_module.html#resolver ) funcionaria no seu caso?proxy.sh
script que lê as variáveis de ambiente e adicionaupstream
entradas dinamicamente para cada uma e, em seguida, inicia o Nginx. Isso funciona muito bem, pois quando executamos nosso contêiner de proxy, podemos passar os upstreams necessários em tempo de execução. Você poderia fazer algo semelhante para habilitar / desabilitar certos upstreams no lançamento (ou como minha configuração, apenas adicionar os necessários no tempo de execução)Respostas:
Se você pode usar um IP estático, então use-o, ele iniciará e retornará
503
se não responder.Use a
resolver
diretiva para apontar para algo que pode resolver o host, independentemente se ele está ativo ou não.Resolva-o no
location
nível, se você não puder fazer o acima (isso permitirá que o Nginx seja iniciado / executado) :fonte
location ~ ^/foo/(.*)$ { proxy_pass http://foo/$1; }
Para mim, a opção 3 da resposta de @ Justin / @ duskwuff resolveu o problema, mas tive que alterar o IP do resolvedor para 127.0.0.11 (servidor DNS do Docker):
Mas, como @ Justin / @ duskwuff mencionou, você pode usar qualquer outro servidor DNS externo.
fonte
A principal vantagem de usar
upstream
é definir um grupo de servidores que pode escutar em portas diferentes e configurar o balanceamento de carga e failover entre eles .No seu caso, você está definindo apenas 1 servidor primário por upstream, portanto, ele deve estar ativo .
Em vez disso, use variáveis para seu
proxy_pass
(s) e lembre-se de lidar com os possíveis erros (404s, 503s) que você pode obter quando um servidor de destino está inativo.fonte
set $variable http://foo
eproxy_pass $variable
mantiver o foo "upstream" (para manter as vantagens que você mencionou), ainda estou encontrando o problema mencionado pelo OP.set $variable foo
eproxy_pass http://$variable
Tive o mesmo problema de "Host não encontrado" porque parte do meu host estava sendo mapeada usando em
$uri
vez de$request_uri
:E quando a solicitação mudou para a sub-solicitação de autenticação, o
$uri
perdeu seu valor inicial. Alterar o mapeamento a ser usado em$request_uri
vez de$uri
resolver meu problema:fonte
Você não pode usar a
--link
opção, em vez disso, você pode usar o mapeamento da porta e vincular o nginx ao endereço do host.Exemplo: execute seu primeiro contêiner docker com
-p 180:80
opção, segundo contêiner com-p 280:80
opção.Execute nginx e defina estes endereços para proxy:
fonte