Problema: Erro "Host Not Found In Upstream" do Nginx
O erro "Host Not Found In Upstream" no Nginx pode ocorrer ao usar contêineres Docker. Esse erro acontece quando o Nginx não consegue resolver ou se conectar ao servidor upstream em sua configuração. Geralmente, é causado por problemas de rede ou configurações incorretas no ambiente Docker.
Resolvendo o Erro "Host Not Found In Upstream" do Nginx
Usando depends_on no docker-compose.yml
A diretiva depends_on no docker-compose.yml ajuda a gerenciar a ordem de inicialização dos contêineres. Ela informa ao Docker para iniciar certos contêineres antes de outros. Isso pode ajudar a evitar o erro "Host Not Found In Upstream" garantindo que os serviços necessários estejam em execução antes do Nginx iniciar.
Para implementar o depends_on em seu arquivo docker-compose.yml, adicione-o sob o serviço Nginx e liste os serviços que ele deve esperar:
version: '3'
services:
nginx:
image: nginx
depends_on:
- php
# Outras configurações do Nginx...
php:
image: php:fpm
# Configurações do PHP...
Dica: Verificar a Prontidão do Serviço
Lembre-se que o depends_on apenas espera que o contêiner inicie, não que o serviço dentro dele esteja totalmente pronto. Para configurações mais complexas, considere usar healthchecks ou scripts wait-for-it para garantir que os serviços estejam totalmente operacionais antes do Nginx iniciar.
Atualizando a configuração do Nginx
Verifique a diretiva fastcgi_pass na sua configuração do Nginx. Certifique-se de que ela use o nome correto do serviço conforme definido no seu arquivo docker-compose.yml. Se o seu serviço PHP é chamado "php" no docker-compose.yml, seu fastcgi_pass deve ser assim:
fastcgi_pass php:9000;
Além disso, verifique se os nomes dos serviços na sua configuração do Nginx correspondem aos do seu arquivo docker-compose.yml. Nomes incompatíveis podem causar o erro "Host Not Found In Upstream".
Implementando scripts wait-for-it
Scripts wait-for-it são scripts shell que pausam a inicialização de um contêiner até que um serviço específico esteja pronto. Esses scripts podem ajudar a evitar o erro "Host Not Found In Upstream" garantindo que o Nginx só inicie após os serviços necessários estarem totalmente operacionais.
Para usar um script wait-for-it na sua configuração Docker:
- Adicione o script ao diretório do seu projeto.
- Atualize seu Dockerfile para incluir o script.
- Altere o comando no seu docker-compose.yml para usar o script wait-for-it:
nginx:
image: nginx
depends_on:
- php
command: ["./wait-for-it.sh", "php:9000", "--", "nginx", "-g", "daemon off;"]
# Outras configurações do Nginx...
Essa abordagem adiciona proteção contra problemas de temporização que podem causar o erro "Host Not Found In Upstream".
Exemplo: Script de Espera Personalizado
Você pode criar um script de espera personalizado adaptado às suas necessidades específicas. Aqui está um exemplo simples em bash:
#!/bin/bash
set -e
host="$1"
shift
cmd="$@"
until nc -z "$host" 9000; do
>&2 echo "PHP-FPM não está disponível - aguardando"
sleep 1
done
>&2 echo "PHP-FPM está pronto - executando comando"
exec $cmd
Salve isso como wait-for-php.sh no diretório do seu projeto, torne-o executável e atualize seu docker-compose.yml para usá-lo:
nginx:
image: nginx
depends_on:
- php
command: ["./wait-for-php.sh", "php", "nginx", "-g", "daemon off;"]
# Outras configurações do Nginx...
Soluções Alternativas para Corrigir o Erro do Nginx
Usando redes Docker
Criar redes Docker personalizadas pode ajudar a corrigir o erro "Host Not Found In Upstream". Redes personalizadas permitem que os contêineres se comuniquem usando seus nomes de serviço como hostnames.
Para criar uma rede personalizada:
- Defina a rede no seu arquivo docker-compose.yml:
networks:
myapp_network:
driver: bridge
- Conecte seus serviços a esta rede:
services:
nginx:
image: nginx
networks:
- myapp_network
php:
image: php:fpm
networks:
- myapp_network
Ao usar uma rede personalizada, você melhora a comunicação entre contêineres e reduz problemas de resolução de hostnames.
Dica: Isolamento de Rede
Crie redes separadas para diferentes partes da sua aplicação para melhorar a segurança e gerenciar o fluxo de tráfego. Por exemplo, você pode ter uma rede frontend para servidores web e uma rede backend para bancos de dados:
networks:
frontend:
driver: bridge
backend:
driver: bridge
services:
nginx:
networks:
- frontend
php:
networks:
- frontend
- backend
database:
networks:
- backend
Implementando healthchecks
Healthchecks no docker-compose.yml podem prevenir o erro "Host Not Found In Upstream" garantindo que um serviço esteja pronto antes que outros serviços que dependem dele iniciem.
Para adicionar healthchecks:
- Inclua um healthcheck no seu docker-compose.yml para o serviço PHP:
services:
php:
image: php:fpm
healthcheck:
test: ["CMD", "php-fpm", "-t"]
interval: 10s
timeout: 5s
retries: 3
- Atualize o serviço Nginx para depender da saúde do serviço PHP:
services:
nginx:
image: nginx
depends_on:
php:
condition: service_healthy
Essa configuração garante que o Nginx só inicie após o serviço PHP estar pronto para aceitar conexões, reduzindo a chance do erro "Host Not Found In Upstream".