¿Cómo solucionar el error de Nginx "Host Not Found In Upstream" en Docker?

Publicado 13 de octubre de 2024

Problema: Error de Nginx "Host Not Found In Upstream"

El error "Host Not Found In Upstream" en Nginx puede ocurrir al usar contenedores Docker. Este error se produce cuando Nginx no puede resolver o conectarse al servidor upstream en su configuración. A menudo se debe a problemas de red o configuraciones incorrectas en el entorno Docker.

Solución del error "Host Not Found In Upstream" de Nginx

Uso de depends_on en docker-compose.yml

La directiva depends_on en docker-compose.yml ayuda a gestionar el orden de inicio de los contenedores. Indica a Docker que inicie ciertos contenedores antes que otros. Esto puede ayudar a prevenir el error "Host Not Found In Upstream" asegurando que los servicios necesarios estén en funcionamiento antes de que Nginx se inicie.

Para implementar depends_on en su archivo docker-compose.yml, añádalo bajo el servicio Nginx y liste los servicios que debe esperar:

version: '3'
services:
  nginx:
    image: nginx
    depends_on:
      - php
    # Otras configuraciones de Nginx...

  php:
    image: php:fpm
    # Configuración de PHP...

Consejo: Verificar la disponibilidad del servicio

Recuerde que depends_on solo espera a que el contenedor se inicie, no a que el servicio dentro esté completamente listo. Para configuraciones más complejas, considere usar healthchecks o scripts wait-for-it para asegurarse de que los servicios estén completamente operativos antes de que Nginx se inicie.

Actualización de la configuración de Nginx

Verifique la directiva fastcgi_pass en su configuración de Nginx. Asegúrese de que utilice el nombre de servicio correcto según se define en su archivo docker-compose.yml. Si su servicio PHP se llama "php" en docker-compose.yml, su fastcgi_pass debería verse así:

fastcgi_pass php:9000;

Además, verifique que los nombres de los servicios en su configuración de Nginx coincidan con los de su archivo docker-compose.yml. Los nombres que no coinciden pueden causar el error "Host Not Found In Upstream".

Implementación de scripts wait-for-it

Los scripts wait-for-it son scripts de shell que pausan el inicio de un contenedor hasta que un servicio específico esté listo. Estos scripts pueden ayudar a prevenir el error "Host Not Found In Upstream" asegurando que Nginx solo se inicie después de que los servicios requeridos estén completamente operativos.

Para usar un script wait-for-it en su configuración Docker:

  1. Añada el script a su directorio de proyecto.
  2. Actualice su Dockerfile para incluir el script.
  3. Cambie el comando en su docker-compose.yml para usar el script wait-for-it:
nginx:
  image: nginx
  depends_on:
    - php
  command: ["./wait-for-it.sh", "php:9000", "--", "nginx", "-g", "daemon off;"]
  # Otras configuraciones de Nginx...

Este enfoque añade protección contra problemas de temporización que pueden causar el error "Host Not Found In Upstream".

Ejemplo: Script de espera personalizado

Puede crear un script de espera personalizado adaptado a sus necesidades específicas. Aquí tiene un ejemplo sencillo en bash:

#!/bin/bash
set -e

host="$1"
shift
cmd="$@"

until nc -z "$host" 9000; do
  >&2 echo "PHP-FPM no está disponible - esperando"
  sleep 1
done

>&2 echo "PHP-FPM está listo - ejecutando comando"
exec $cmd

Guarde esto como wait-for-php.sh en su directorio de proyecto, hágalo ejecutable y actualice su docker-compose.yml para usarlo:

nginx:
  image: nginx
  depends_on:
    - php
  command: ["./wait-for-php.sh", "php", "nginx", "-g", "daemon off;"]
  # Otras configuraciones de Nginx...

Soluciones alternativas para corregir el error de Nginx

Uso de redes Docker

Crear redes Docker personalizadas puede ayudar a solucionar el error "Host Not Found In Upstream". Las redes personalizadas permiten que los contenedores se comuniquen usando sus nombres de servicio como nombres de host.

Para crear una red personalizada:

  1. Defina la red en su archivo docker-compose.yml:
networks:
  myapp_network:
    driver: bridge
  1. Conecte sus servicios a esta red:
services:
  nginx:
    image: nginx
    networks:
      - myapp_network

  php:
    image: php:fpm
    networks:
      - myapp_network

Al usar una red personalizada, mejora la comunicación entre contenedores y reduce los problemas de resolución de nombres de host.

Consejo: Aislamiento de red

Cree redes separadas para diferentes partes de su aplicación para mejorar la seguridad y gestionar el flujo de tráfico. Por ejemplo, puede tener una red frontend para servidores web y una red backend para bases de datos:

networks:
  frontend:
    driver: bridge
  backend:
    driver: bridge

services:
  nginx:
    networks:
      - frontend
  php:
    networks:
      - frontend
      - backend
  database:
    networks:
      - backend

Implementación de healthchecks

Los healthchecks en docker-compose.yml pueden prevenir el error "Host Not Found In Upstream" asegurando que un servicio esté listo antes de que se inicien otros servicios que dependen de él.

Para añadir healthchecks:

  1. Incluya un healthcheck en su docker-compose.yml para el servicio PHP:
services:
  php:
    image: php:fpm
    healthcheck:
      test: ["CMD", "php-fpm", "-t"]
      interval: 10s
      timeout: 5s
      retries: 3
  1. Actualice el servicio Nginx para que dependa de la salud del servicio PHP:
services:
  nginx:
    image: nginx
    depends_on:
      php:
        condition: service_healthy

Esta configuración asegura que Nginx solo se inicie después de que el servicio PHP esté listo para aceptar conexiones, reduciendo la probabilidad del error "Host Not Found In Upstream".