Come risolvere l'errore Nginx "Host Not Found In Upstream" in Docker?

Pubblicato 13 ottobre 2024

Problema: Errore Nginx "Host Not Found In Upstream"

L'errore "Host Not Found In Upstream" in Nginx può verificarsi quando si utilizzano container Docker. Questo errore si verifica quando Nginx non riesce a risolvere o connettersi al server upstream nella sua configurazione. Spesso deriva da problemi di rete o impostazioni errate nell'ambiente Docker.

Risoluzione dell'Errore Nginx "Host Not Found In Upstream"

Utilizzare depends_on in docker-compose.yml

La direttiva depends_on in docker-compose.yml aiuta a gestire l'ordine di avvio dei container. Indica a Docker di avviare determinati container prima di altri. Questo può aiutare a prevenire l'errore "Host Not Found In Upstream" assicurando che i servizi necessari siano in esecuzione prima dell'avvio di Nginx.

Per implementare depends_on nel file docker-compose.yml, aggiungilo sotto il servizio Nginx ed elenca i servizi che dovrebbe attendere:

version: '3'
services:
  nginx:
    image: nginx
    depends_on:
      - php
    # Altre configurazioni Nginx...

  php:
    image: php:fpm
    # Configurazione PHP...

Suggerimento: Verifica della Prontezza del Servizio

Ricorda che depends_on attende solo l'avvio del container, non che il servizio al suo interno sia completamente pronto. Per configurazioni più complesse, considera l'uso di healthcheck o script wait-for-it per assicurarti che i servizi siano completamente operativi prima dell'avvio di Nginx.

Aggiornamento della configurazione Nginx

Controlla la direttiva fastcgi_pass nella tua configurazione Nginx. Assicurati che utilizzi il nome del servizio corretto come definito nel tuo file docker-compose.yml. Se il tuo servizio PHP si chiama "php" in docker-compose.yml, il tuo fastcgi_pass dovrebbe apparire così:

fastcgi_pass php:9000;

Inoltre, verifica che i nomi dei servizi nella tua configurazione Nginx corrispondano a quelli nel tuo file docker-compose.yml. Nomi non corrispondenti possono causare l'errore "Host Not Found In Upstream".

Implementazione di script wait-for-it

Gli script wait-for-it sono script shell che mettono in pausa l'avvio di un container fino a quando un servizio specifico non è pronto. Questi script possono aiutare a prevenire l'errore "Host Not Found In Upstream" assicurando che Nginx si avvii solo dopo che i servizi richiesti sono completamente operativi.

Per utilizzare uno script wait-for-it nella tua configurazione Docker:

  1. Aggiungi lo script alla directory del tuo progetto.
  2. Aggiorna il tuo Dockerfile per includere lo script.
  3. Modifica il comando nel tuo docker-compose.yml per utilizzare lo script wait-for-it:
nginx:
  image: nginx
  depends_on:
    - php
  command: ["./wait-for-it.sh", "php:9000", "--", "nginx", "-g", "daemon off;"]
  # Altre configurazioni Nginx...

Questo approccio aggiunge una protezione contro i problemi di temporizzazione che possono causare l'errore "Host Not Found In Upstream".

Esempio: Script di Attesa Personalizzato

Puoi creare uno script di attesa personalizzato adattato alle tue esigenze specifiche. Ecco un semplice esempio in bash:

#!/bin/bash
set -e

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

until nc -z "$host" 9000; do
  >&2 echo "PHP-FPM non è disponibile - in attesa"
  sleep 1
done

>&2 echo "PHP-FPM è attivo - esecuzione del comando"
exec $cmd

Salva questo come wait-for-php.sh nella directory del tuo progetto, rendilo eseguibile e aggiorna il tuo docker-compose.yml per utilizzarlo:

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

Soluzioni Alternative per Risolvere l'Errore Nginx

Utilizzo di reti Docker

La creazione di reti Docker personalizzate può aiutare a risolvere l'errore "Host Not Found In Upstream". Le reti personalizzate consentono ai container di comunicare utilizzando i nomi dei loro servizi come nomi host.

Per creare una rete personalizzata:

  1. Definisci la rete nel tuo file docker-compose.yml:
networks:
  myapp_network:
    driver: bridge
  1. Connetti i tuoi servizi a questa rete:
services:
  nginx:
    image: nginx
    networks:
      - myapp_network

  php:
    image: php:fpm
    networks:
      - myapp_network

Utilizzando una rete personalizzata, migliori la comunicazione tra i container e riduci i problemi di risoluzione dei nomi host.

Suggerimento: Isolamento della Rete

Crea reti separate per diverse parti della tua applicazione per migliorare la sicurezza e gestire il flusso del traffico. Ad esempio, puoi avere una rete frontend per i server web e una rete backend per i database:

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

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

Implementazione di healthcheck

Gli healthcheck in docker-compose.yml possono prevenire l'errore "Host Not Found In Upstream" assicurando che un servizio sia pronto prima che altri servizi che dipendono da esso si avviino.

Per aggiungere healthcheck:

  1. Includi un healthcheck nel tuo docker-compose.yml per il servizio PHP:
services:
  php:
    image: php:fpm
    healthcheck:
      test: ["CMD", "php-fpm", "-t"]
      interval: 10s
      timeout: 5s
      retries: 3
  1. Aggiorna il servizio Nginx per dipendere dallo stato di salute del servizio PHP:
services:
  nginx:
    image: nginx
    depends_on:
      php:
        condition: service_healthy

Questa configurazione assicura che Nginx si avvii solo dopo che il servizio PHP è pronto ad accettare connessioni, riducendo la possibilità dell'errore "Host Not Found In Upstream".