Hôtes Virtuels Nginx : Héberger Plusieurs Sites Web sur un Seul Serveur

Exploitez la puissance des hôtes virtuels Nginx (server blocks) pour héberger efficacement plusieurs sites web ou sous-domaines sur un seul serveur. Ce guide propose un tutoriel complet et étape par étape, couvrant la configuration des répertoires, la création de fichiers de configuration, l'activation des server blocks et les tests Nginx. Apprenez les meilleures pratiques pour les sous-domaines, les server blocks par défaut, l'intégration HTTPS et la journalisation dédiée. Des exemples pratiques et des conseils de dépannage essentiels vous aideront à maîtriser l'hébergement multi-sites avec Nginx, optimisant l'utilisation des ressources et simplifiant la gestion du serveur web.

Hôtes Virtuels Nginx : Héberger Plusieurs Sites Web sur un Seul Serveur

Faire fonctionner plusieurs petits sites à partir d'un seul serveur est une tâche courante pour Nginx. Vous pourriez avoir un site d'entreprise, un site de documentation, une application de préproduction et un portail client, tous atterrissant sur la même machine. Nginx les sépare à l'aide de blocs server. Les utilisateurs d'Apache appellent souvent la même idée des hôtes virtuels, donc vous verrez les deux termes utilisés dans les tutoriels et les panneaux d'hébergement.

La partie importante est simple : Nginx examine le port, l'adresse IP et l'en-tête Host, puis choisit le bloc server correspondant. Si le mauvais site se charge, le problème n'est généralement pas mystérieux. Il s'agit souvent d'un enregistrement DNS manquant, d'une faute de frappe dans server_name, d'un serveur par défaut qui intercepte la requête, ou de deux fichiers revendiquant le même nom.

Comprendre les Blocs Serveur Nginx (Hôtes Virtuels)

À la base, un bloc serveur Nginx est une directive de configuration définie dans le fichier de configuration Nginx (nginx.conf ou fichiers inclus). Chaque bloc server définit la configuration pour un hôte virtuel spécifique, dictant comment Nginx doit répondre aux requêtes pour un domaine ou un ensemble de domaines particulier. Nginx utilise la directive listen pour spécifier l'adresse IP et le port sur lesquels il doit écouter, et la directive server_name pour identifier les noms de domaine ou noms d'hôte auxquels ce bloc serveur doit répondre.

Lorsqu'une requête arrive, Nginx examine l'en-tête Host de la requête HTTP et le compare aux directives server_name de ses blocs serveur configurés. Il sert ensuite le contenu défini dans le bloc serveur correspondant. Si aucun server_name ne correspond, Nginx utilise généralement le bloc serveur par défaut (le premier bloc server ou un bloc explicitement marqué comme default_server).

Prérequis

Avant de commencer, assurez-vous d'avoir les éléments suivants :

  1. Nginx Installé : Nginx doit être installé et en cours d'exécution sur votre serveur. Sinon, vous pouvez généralement l'installer via le gestionnaire de paquets de votre système (par exemple, sudo apt update && sudo apt install nginx sur Ubuntu/Debian, sudo yum install nginx sur CentOS/RHEL).
  2. Noms de Domaine : Vous avez besoin d'au moins deux noms de domaine (par exemple, example1.com et example2.com) ou sous-domaines (par exemple, blog.example.com et app.example.com) que vous souhaitez héberger. Les enregistrements DNS A/AAAA de ces domaines doivent pointer vers l'adresse IP publique de votre serveur.
  3. Structure de Répertoires de Base : Un plan pour l'emplacement de vos fichiers de site web. Une pratique courante est /var/www/votredomaine.com/html.
  4. Privilèges Sudo : Vous aurez besoin d'un accès sudo pour modifier les fichiers de configuration Nginx.

Guide de Configuration Étape par Étape

Configurons deux hôtes virtuels : example1.com et example2.com.

Étape 1 : Créer la Structure de Répertoires pour les Sites Web

Tout d'abord, créez les répertoires racines pour chacun de vos sites web. C'est là que leurs fichiers HTML, CSS, JavaScript et autres fichiers statiques seront stockés. Un emplacement courant est /var/www/.

sudo mkdir -p /var/www/example1.com/html
sudo mkdir -p /var/www/example2.com/html

# Définir le propriétaire sur votre utilisateur (remplacez $USER par votre nom d'utilisateur) pour permettre l'édition
sudo chown -R $USER:$USER /var/www/example1.com/html
sudo chown -R $USER:$USER /var/www/example2.com/html

# Définir les permissions de lecture pour le serveur web
sudo chmod -R 755 /var/www

Ensuite, créez un fichier index.html simple dans chaque répertoire pour tester la configuration :

Pour /var/www/example1.com/html/index.html :

<!-- /var/www/example1.com/html/index.html -->
<!DOCTYPE html>
<html>
<head>
    <title>Bienvenue sur Example1.com !</title>
</head>
<body>
    <h1>Succès ! Ceci est Example1.com.</h1>
    <p>Cet hôte virtuel fonctionne correctement.</p>
</body>
</html>

Pour /var/www/example2.com/html/index.html :

<!-- /var/www/example2.com/html/index.html -->
<!DOCTYPE html>
<html>
<head>
    <title>Bienvenue sur Example2.com !</title>
</head>
<body>
    <h1>Succès ! Ceci est Example2.com.</h1>
    <p>Cet hôte virtuel fonctionne aussi !</p>
</body>
</html>

Étape 2 : Créer les Fichiers de Configuration des Blocs Serveur Nginx

Nginx charge généralement les configurations des blocs serveur à partir des fichiers du répertoire /etc/nginx/sites-enabled/. Ces fichiers sont généralement des liens symboliques vers des configurations stockées dans /etc/nginx/sites-available/. Cette séparation vous permet de stocker des configurations qui ne sont pas encore actives ou d'activer/désactiver facilement des sites.

Créez un nouveau fichier de configuration pour example1.com :

sudo nano /etc/nginx/sites-available/example1.com.conf

Ajoutez le contenu suivant :

# /etc/nginx/sites-available/example1.com.conf
server {
    listen 80;
    listen [::]:80;

    root /var/www/example1.com/html;
    index index.html index.htm index.nginx-debian.html;

    server_name example1.com www.example1.com;

    location / {
        try_files $uri $uri/ =404;
    }

    access_log /var/log/nginx/example1.com_access.log;
    error_log /var/log/nginx/example1.com_error.log;
}

Explication des Directives :

  • listen 80; : Nginx écoute sur le port 80 (HTTP standard). listen [::]:80; est pour IPv6.
  • root /var/www/example1.com/html; : Spécifie la racine des documents pour ce bloc serveur. Nginx cherchera les fichiers dans ce répertoire.
  • index index.html ...; : Définit le fichier par défaut que Nginx doit servir lorsqu'un répertoire est demandé (par exemple, lorsque quelqu'un visite example1.com/).
  • server_name example1.com www.example1.com; : C'est crucial. Cela indique à Nginx de répondre aux requêtes pour example1.com ou www.example1.com en utilisant la configuration de ce bloc serveur.
  • location / { ... } : Un bloc définissant comment gérer les requêtes pour des URI spécifiques. try_files tente de servir un fichier directement ($uri), puis un répertoire ($uri/), et enfin retourne une erreur 404 Not Found.
  • access_log et error_log : Spécifie des fichiers journaux séparés pour ce site spécifique, ce qui est une bonne pratique pour un débogage et une analyse plus faciles.

Maintenant, créez un fichier de configuration similaire pour example2.com :

sudo nano /etc/nginx/sites-available/example2.com.conf

Ajoutez le contenu suivant :

# /etc/nginx/sites-available/example2.com.conf
server {
    listen 80;
    listen [::]:80;

    root /var/www/example2.com/html;
    index index.html index.htm index.nginx-debian.html;

    server_name example2.com www.example2.com;

    location / {
        try_files $uri $uri/ =404;
    }

    access_log /var/log/nginx/example2.com_access.log;
    error_log /var/log/nginx/example2.com_error.log;
}

Étape 3 : Activer les Blocs Serveur

Pour activer ces configurations, créez des liens symboliques du répertoire sites-available vers le répertoire sites-enabled. Cela indique à Nginx d'inclure ces fichiers lorsqu'il démarre.

sudo ln -s /etc/nginx/sites-available/example1.com.conf /etc/nginx/sites-enabled/
sudo ln -s /etc/nginx/sites-available/example2.com.conf /etc/nginx/sites-enabled/

Étape 4 : Tester la Configuration Nginx

Il est crucial de tester votre configuration Nginx pour détecter les erreurs de syntaxe avant de recharger. Cela empêche Nginx de ne pas redémarrer en raison d'une faute de frappe.

sudo nginx -t

Vous devriez voir une sortie similaire à celle-ci, indiquant un succès :

nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

Si vous voyez des erreurs, corrigez-les dans les fichiers de configuration respectifs et réexécutez sudo nginx -t jusqu'à ce qu'il réussisse.

Étape 5 : Redémarrer Nginx

Appliquez la nouvelle configuration en redémarrant ou en rechargeant Nginx. reload est généralement préféré car il permet à Nginx de charger de nouvelles configurations sans interrompre les connexions actives.

sudo systemctl reload nginx
# Ou, si le rechargement ne fonctionne pas ou pour les nouvelles installations :
sudo systemctl restart nginx

Étape 6 : Mettre à Jour les Enregistrements DNS

Assurez-vous que les enregistrements DNS A pour example1.com, www.example1.com, example2.com et www.example2.com pointent tous vers l'adresse IP de votre serveur Nginx. Sans entrées DNS correctes, votre navigateur ne saura pas où trouver vos sites web.

Une fois la propagation DNS terminée (cela peut prendre de quelques minutes à plusieurs heures), vous devriez pouvoir visiter http://example1.com et http://example2.com dans votre navigateur web et voir les pages index.html respectives.

Scénarios Avancés et Meilleures Pratiques

Hébergement de Sous-domaines

L'hébergement de sous-domaines (par exemple, blog.example.com, shop.example.com) fonctionne exactement comme l'hébergement de domaines séparés. Il vous suffit de définir un nouveau bloc serveur avec le sous-domaine comme server_name.

Exemple pour blog.example.com :

# /etc/nginx/sites-available/blog.example.com.conf
server {
    listen 80;
    listen [::]:80;

    root /var/www/blog.example.com/html;
    index index.html;

    server_name blog.example.com;

    location / {
        try_files $uri $uri/ =404;
    }
}

N'oubliez pas de créer le répertoire (/var/www/blog.example.com/html), de créer un index.html, de créer le lien symbolique et de recharger Nginx.

Le Bloc Serveur par Défaut

Il est de bonne pratique d'avoir un bloc serveur par défaut qui intercepte les requêtes pour les noms de domaine qui ne correspondent à aucune autre directive server_name sur votre serveur. Cela empêche les requêtes inconnues d'être servies par le "premier" hôte virtuel que Nginx trouve, ou vous permet de servir une page générique "site non trouvé".

Typiquement, le premier bloc server dans votre nginx.conf ou sites-enabled est implicitement le défaut. Vous pouvez en définir un explicitement en utilisant default_server :

server {
    listen 80 default_server;
    listen [::]:80 default_server;

    server_name _;
    # Le tiret bas `_` est un nom de domaine inexistant qui ne correspondra jamais à une vraie requête.
    # Vous pouvez également utiliser localhost.

    root /var/www/default_site/html;
    index index.html;

    location / {
        return 444; # Retourne une erreur 444 spécifique à Nginx (pas de réponse) pour les hôtes inconnus
        # Ou, servez une page d'accueil générique :
        # try_files $uri $uri/ =404;
    }
}

Avertissement : Si vous définissez un bloc default_server, assurez-vous qu'un seul bloc server sur un port listen donné a le drapeau default_server, sinon Nginx enregistrera un avertissement.

Sécurisation des Hôtes Virtuels avec HTTPS (SSL/TLS)

Pour les sites web en production, l'activation de HTTPS est essentielle. Cela implique d'obtenir un certificat SSL/TLS (par exemple, via Let's Encrypt en utilisant Certbot) et de configurer Nginx pour écouter sur le port 443 avec le certificat.

Un bloc serveur HTTPS typique ressemble à ceci (après avoir obtenu les certificats) :

server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;

    server_name example1.com www.example1.com;

    root /var/www/example1.com/html;
    index index.html;

    ssl_certificate /etc/letsencrypt/live/example1.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example1.com/privkey.pem;

    # Inclure d'autres configurations SSL (chiffrements, protocoles, etc.)
    include /etc/nginx/snippets/ssl-params.conf;

    location / {
        try_files $uri $uri/ =404;
    }
}

# Facultatif : Redirection HTTP vers HTTPS pour ce domaine
server {
    listen 80;
    listen [::]:80;
    server_name example1.com www.example1.com;
    return 301 https://$host$request_uri;
}

Il est courant d'avoir un bloc serveur HTTP séparé dont le seul but est de rediriger tout le trafic vers son homologue HTTPS.

Si vous utilisez Certbot, il peut créer ou modifier ces blocs pour vous. C'est pratique, mais vous devriez quand même lire le fichier résultant. Les outils de certificat automatisés ajoutent parfois une logique de redirection à un endroit que vous n'auriez pas choisi vous-même, et les redirections dupliquées peuvent rendre le dépannage plus difficile.

Journalisation pour Chaque Site

Comme montré dans les exemples, dédier des fichiers access_log et error_log séparés pour chaque hôte virtuel est une bonne pratique. Cela facilite considérablement le débogage des problèmes et l'analyse du trafic pour des sites web individuels sans avoir à fouiller dans des journaux combinés.

Structure des Fichiers de Configuration

Pour les déploiements plus importants, envisagez d'organiser vos fichiers de configuration Nginx comme ceci :

  • nginx.conf : Configuration principale, inclut conf.d/*.conf et sites-enabled/*.
  • conf.d/ : Paramètres généraux à l'échelle du serveur (par exemple, Gzip, mise en cache).
  • snippets/ : Extrait de configuration Nginx réutilisables (par exemple, paramètres SSL, blocs location courants).
  • sites-available/ : Blocs server individuels pour chaque site web.
  • sites-enabled/ : Liens symboliques vers les configurations actives dans sites-available/.

Dépannage des Problèmes Courants

  • Erreur 403 Interdit : Cela signifie généralement que Nginx n'a pas accès en lecture aux fichiers ou répertoires de votre site web. Vérifiez les permissions des fichiers et répertoires (par exemple, sudo chmod -R 755 /var/www/votredomaine.com/html et assurez-vous que l'utilisateur Nginx, généralement www-data ou nginx, peut les lire).
  • Erreur 404 Non Trouvé : Vérifiez que la directive root dans votre bloc serveur pointe vers le bon répertoire et que votre fichier index.html existe à cet emplacement. Assurez-vous également que try_files est correctement configuré.
  • Le Mauvais Site se Charge : Cela indique souvent un problème avec la directive server_name. Assurez-vous que le server_name correspond exactement au nom de domaine auquel vous essayez d'accéder (y compris www. ou les sous-domaines). Vérifiez également vos enregistrements DNS.
  • Nginx ne Démarre/Recharge Pas : Utilisez toujours sudo nginx -t pour tester votre configuration avant d'essayer de recharger ou redémarrer Nginx. Les messages d'erreur identifieront la ligne et le fichier où l'erreur de syntaxe s'est produite.
  • Problèmes DNS : Si vous pouvez accéder à votre site par adresse IP mais pas par nom de domaine, c'est presque certainement un problème DNS. Utilisez dig ou nslookup pour vérifier que les enregistrements A de votre domaine pointent vers la bonne IP du serveur.

Tester Avant que le DNS ne Soit Prêt

Vous n'avez pas besoin d'attendre le DNS public pour tester le côté Nginx. Vous pouvez envoyer une requête avec un en-tête Host personnalisé :

curl -H "Host: example1.com" http://203.0.113.10/
curl -H "Host: example2.com" http://203.0.113.10/

Remplacez 203.0.113.10 par l'IP de votre serveur. Si chaque commande renvoie la bonne page de test, la correspondance du bloc serveur fonctionne. Si les deux commandes renvoient la même page, vérifiez si les deux fichiers sont activés, si server_name est correct et si un bloc par défaut intercepte la requête.

Pour HTTPS, le test est un peu différent car TLS utilise SNI avant que l'en-tête HTTP Host ne soit traité :

curl --resolve example1.com:443:203.0.113.10 https://example1.com/

Cette commande indique à curl de se connecter à l'IP de votre serveur tout en utilisant example1.com pour TLS et HTTP. C'est l'un des moyens les plus rapides de tester un nouvel hôte virtuel HTTPS avant de modifier le DNS.

Un Modèle Multi-Sites Maintenable

Pour une poignée de sites statiques, les exemples ci-dessus suffisent. Une fois que vous hébergez plusieurs applications, répétez moins et centralisez uniquement les parties qui sont vraiment partagées. Par exemple, mettez les en-têtes de sécurité courants, la compression et les paramètres SSL dans des extraits, mais gardez la root, le server_name, l'upstream et les journaux de chaque site visibles dans son propre fichier.

Évitez de copier un gros bloc de production d'un domaine à un autre sans lire chaque ligne. C'est ainsi que les erreurs de server_name, les mauvais chemins de certificat et les fichiers journaux partagés s'infiltrent. Une liste de vérification pratique est courte :

  • Est-ce que server_name inclut tous les noms d'hôte que les utilisateurs taperont ?
  • Est-ce que root ou proxy_pass pointe vers ce site, pas le précédent ?
  • Les journaux d'accès et d'erreur sont-ils suffisamment séparés pour déboguer ce site seul ?
  • Est-ce que nginx -t réussit avant le rechargement ?
  • Est-ce que curl -H "Host: ..." ou curl --resolve renvoie le site attendu ?

Remarques Finales

Les hôtes virtuels Nginx sont fiables lorsque chaque site a un bloc serveur clair, un server_name correct et un repli par défaut prévisible. Gardez les fichiers ennuyeux. Testez chaque modification avant de recharger. Utilisez des journaux dédiés lorsque les sites sont importants. La plupart des problèmes multi-sites Nginx deviennent faciles à résoudre une fois que vous pouvez prouver si le DNS, TLS/SNI ou la correspondance du bloc serveur est la partie qui a échoué.