Comment résoudre l'erreur Nginx "Host Not Found In Upstream" dans Docker ?

Publié 13 octobre 2024

Problème : Erreur Nginx "Host Not Found In Upstream"

L'erreur "Host Not Found In Upstream" dans Nginx peut survenir lors de l'utilisation de conteneurs Docker. Cette erreur se produit lorsque Nginx ne parvient pas à résoudre ou à se connecter au serveur en amont dans sa configuration. Elle provient souvent de problèmes de réseau ou de paramètres incorrects dans l'environnement Docker.

Résolution de l'erreur Nginx "Host Not Found In Upstream"

Utilisation de depends_on dans docker-compose.yml

La directive depends_on dans docker-compose.yml aide à gérer l'ordre de démarrage des conteneurs. Elle indique à Docker de démarrer certains conteneurs avant d'autres. Cela peut aider à prévenir l'erreur "Host Not Found In Upstream" en s'assurant que les services requis sont en cours d'exécution avant le démarrage de Nginx.

Pour implémenter depends_on dans votre fichier docker-compose.yml, ajoutez-le sous le service Nginx et listez les services qu'il doit attendre :

version: '3'
services:
  nginx:
    image: nginx
    depends_on:
      - php
    # Autres configurations Nginx...

  php:
    image: php:fpm
    # Configuration PHP...

Conseil: Vérifier la disponibilité des services

N'oubliez pas que depends_on attend seulement que le conteneur démarre, pas que le service à l'intérieur soit entièrement prêt. Pour des configurations plus complexes, envisagez d'utiliser des healthchecks ou des scripts wait-for-it pour vous assurer que les services sont pleinement opérationnels avant le démarrage de Nginx.

Mise à jour de la configuration Nginx

Vérifiez la directive fastcgi_pass dans votre configuration Nginx. Assurez-vous qu'elle utilise le nom de service correct tel que défini dans votre fichier docker-compose.yml. Si votre service PHP est nommé "php" dans docker-compose.yml, votre fastcgi_pass devrait ressembler à ceci :

fastcgi_pass php:9000;

Vérifiez également que les noms de services dans votre configuration Nginx correspondent à ceux de votre fichier docker-compose.yml. Des noms non concordants peuvent provoquer l'erreur "Host Not Found In Upstream".

Implémentation de scripts wait-for-it

Les scripts wait-for-it sont des scripts shell qui mettent en pause le démarrage d'un conteneur jusqu'à ce qu'un service spécifique soit prêt. Ces scripts peuvent aider à prévenir l'erreur "Host Not Found In Upstream" en s'assurant que Nginx ne démarre qu'après que les services requis soient pleinement opérationnels.

Pour utiliser un script wait-for-it dans votre configuration Docker :

  1. Ajoutez le script à votre répertoire de projet.
  2. Mettez à jour votre Dockerfile pour inclure le script.
  3. Modifiez la commande dans votre docker-compose.yml pour utiliser le script wait-for-it :
nginx:
  image: nginx
  depends_on:
    - php
  command: ["./wait-for-it.sh", "php:9000", "--", "nginx", "-g", "daemon off;"]
  # Autres configurations Nginx...

Cette approche ajoute une protection contre les problèmes de timing qui peuvent causer l'erreur "Host Not Found In Upstream".

Exemple: Script d'attente personnalisé

Vous pouvez créer un script d'attente personnalisé adapté à vos besoins spécifiques. Voici un exemple simple en bash :

#!/bin/bash
set -e

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

until nc -z "$host" 9000; do
  >&2 echo "PHP-FPM n'est pas disponible - en attente"
  sleep 1
done

>&2 echo "PHP-FPM est prêt - exécution de la commande"
exec $cmd

Sauvegardez ce script sous le nom wait-for-php.sh dans votre répertoire de projet, rendez-le exécutable, et mettez à jour votre docker-compose.yml pour l'utiliser :

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

Solutions alternatives pour résoudre l'erreur Nginx

Utilisation des réseaux Docker

La création de réseaux Docker personnalisés peut aider à résoudre l'erreur "Host Not Found In Upstream". Les réseaux personnalisés permettent aux conteneurs de communiquer en utilisant leurs noms de service comme noms d'hôte.

Pour créer un réseau personnalisé :

  1. Définissez le réseau dans votre fichier docker-compose.yml :
networks:
  myapp_network:
    driver: bridge
  1. Connectez vos services à ce réseau :
services:
  nginx:
    image: nginx
    networks:
      - myapp_network

  php:
    image: php:fpm
    networks:
      - myapp_network

En utilisant un réseau personnalisé, vous améliorez la communication entre les conteneurs et réduisez les problèmes de résolution de noms d'hôte.

Conseil: Isolation réseau

Créez des réseaux séparés pour différentes parties de votre application afin d'améliorer la sécurité et de gérer le flux de trafic. Par exemple, vous pouvez avoir un réseau frontend pour les serveurs web et un réseau backend pour les bases de données :

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

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

Implémentation de healthchecks

Les healthchecks dans docker-compose.yml peuvent prévenir l'erreur "Host Not Found In Upstream" en s'assurant qu'un service est prêt avant que d'autres services qui en dépendent ne démarrent.

Pour ajouter des healthchecks :

  1. Incluez un healthcheck dans votre docker-compose.yml pour le service PHP :
services:
  php:
    image: php:fpm
    healthcheck:
      test: ["CMD", "php-fpm", "-t"]
      interval: 10s
      timeout: 5s
      retries: 3
  1. Mettez à jour le service Nginx pour dépendre de la santé du service PHP :
services:
  nginx:
    image: nginx
    depends_on:
      php:
        condition: service_healthy

Cette configuration s'assure que Nginx ne démarre qu'après que le service PHP soit prêt à accepter des connexions, réduisant ainsi les chances d'obtenir l'erreur "Host Not Found In Upstream".