molitor.photography

VirtualHost : monter plusieurs sites sur un seul serveur pas à pas

2026-11-13

Héberger plusieurs sites sur une seule machine, c'est l'un des gestes les plus courants de l'administration Apache. Et pourtant, c'est aussi l'un de ceux où l'on se trompe le plus souvent. Le site par défaut qui répond à la place du vôtre, le 403 inexpliqué, le certificat qui ne s'applique pas au bon domaine, autant de petits drames qui peuvent gâcher une soirée. J'ai monté, cassé et remonté des dizaines de VirtualHost au fil des années, et je peux vous dire que la plupart des problèmes viennent de détails simples qu'on saute parce qu'on est pressé. Alors ici, on va prendre le temps. On va voir comment écrire un bloc propre, comment activer un site, comment passer en HTTPS sans se tromper de domaine, et comment vérifier que tout fonctionne. Pas de théorie inutile, juste ce qu'il faut pour que ça marche.

Un VirtualHost, c'est finalement une idée simple : Apache écoute sur une adresse et un port, et selon le nom d'hôte demandé par le client, il sert un site différent. Trois lignes suffisent pour un site basique, mais derrière cette simplicité se cache une cascade de décisions : name-based ou IP-based, HTTP seul ou HTTPS, un site par fichier ou tout dans un bloc. Les choix que vous ferez au départ conditionneront la maintenance pour des années. C'est pour cela qu'il vaut la peine de comprendre la logique avant de copier-coller un fichier trouvé sur un forum.

Pourquoi le VirtualHost reste la brique de base d'un serveur Apache en 2026

On pourrait croire que les conteneurs et les architectures distribuées ont rendu les VirtualHost obsolètes. Ce n'est pas le cas. La plupart des serveurs Apache en production utilisent encore des VirtualHost, même en environnement conteneurisé. La raison est simple : c'est le moyen le plus direct et le plus lisible de définir plusieurs sites sur une même instance. Les fichiers de configuration sont versionnables, auditables et testables. Et quand un site plante, on sait exactement où regarder. C'est un avantage considérable quand on gère plusieurs projets.

Ce qu'un VirtualHost permet vraiment, sans le folklore

Un VirtualHost permet de définir un contexte de serveur virtuel, dans lequel on place les directives ServerName, DocumentRoot, ErrorLog, CustomLog et éventuellement des règles SSL, des alias, des redirections ou des restrictions d'accès. Tout ce qui est dans le bloc s'applique au site correspondant, dans la limite des directives autorisées en contexte v. C'est un périmètre clairement délimité, ce qui est très pratique pour isoler des configurations. On peut même définir un VirtualHost dont la DocumentRoot pointe vers un répertoire partagé, par exemple pour du contenu statique commun.

Name-based ou IP-based : le choix qui conditionne tout le reste

Le name-based virtual hosting héberge plusieurs sites sur la même adresse IP, en se basant sur l'en-tête Host. C'est la méthode la plus courante en 2026, et c'est aussi la plus économe en adresses IP. Le IP-based réserve une adresse IP par site, ce qui est rarement nécessaire aujourd'hui. La différence est importante en HTTPS : avec le name-based, il faut SNI (Server Name Indication) pour que le client indique le nom d'hôte au moment de la négociation TLS, ce qui est supporté par tous les navigateurs modernes. Sans SNI, on ne peut servir qu'un seul certificat par adresse IP, ce qui était le quotidien il y a quinze ans. Aujourd'hui, la question ne se pose plus vraiment pour un serveur public, mais il faut la connaître.

Les prérequis avant d'écrire la première ligne

Avant d'écrire un VirtualHost, quelques vérifications s'imposent. Ce n'est pas de la paperasse, c'est ce qui évite de perdre du temps ensuite. Un prérequis oublié, et vous passerez une heure à chercher pourquoi votre site ne répond pas.

Vérifier la version d'Apache et les modules nécessaires

La commande apachectl -v ou httpd -v vous donne la version exacte. En 2026, la branche 2.4 est la norme, et la 2.2 n'est plus supportée. Les modules indispensables pour un site basique sont mod_ssl pour HTTPS, mod_rewrite si vous utilisez des règles de réécriture, et parfois mod_headers pour ajouter des en-têtes de sécurité. Sur Debian et Ubuntu, a2enmod active les modules facilement. Sur RHEL, il faut éditer la liste des LoadModule ou activer les modules via la configuration.

Nom de domaine, DNS et certificats : la checklist minimale

Avant de configurer Apache, vérifiez que votre nom de domaine pointe bien vers l'adresse IP du serveur. Un dig ou un nslookup vous donnera la réponse. Si le DNS n'est pas à jour, aucun test ne fonctionnera, et vous risquez de chercher un problème Apache là où il n'y en a pas. Pour les certificats, un domaine valide est nécessaire. Les certificats Let's Encrypt exigent un défi HTTP-01 ou DNS-01, qui suppose que le domaine soit déjà résolvable. Bref, l'ordre logique est : DNS d'abord, Apache ensuite, certificat enfin. Inverser cet ordre mène à des impasses.

Arborescence des fichiers et permissions Unix

Un répertoire de site mal configuré en permissions produit un 403 difficile à diagnostiquer. Apache doit pouvoir lire les fichiers, mais pas forcément écrire. En pratique, l'utilisateur Apache (souvent www-data sur Debian, apache sur RHEL) doit avoir les droits de lecture sur DocumentRoot et sur les parents. Le répertoire doit être traversable (bit x), et les fichiers lisibles (bit r). Sur les répertoires sensibles, on limite les droits au strict nécessaire. Une arborescence classique ressemble à ceci :

  • /var/www/example.com/public_html pour le contenu public
  • /var/www/example.com/logs pour les journaux dédiés
  • /var/www/example.com/ssl pour les certificats si vous n'utilisez pas Let's Encrypt
  • /var/log/apache2 ou /var/log/httpd selon la distribution

Ce n'est pas la seule organisation possible, mais elle a l'avantage d'être claire. Et la clarté paie toujours sur le long terme.

Anatomie complète d'un bloc VirtualHost

Prenons un VirtualHost HTTP classique pour un site nommé example.com. Le bloc doit contenir quelques directives obligatoires et quelques directives fortement recommandées. La nuance entre les deux est importante : un bloc mal structuré fonctionnera peut-être, mais laissera passer des problèmes silencieux.

ServerName, ServerAlias et le rôle du premier bloc

ServerName définit le nom principal du site. ServerAlias ajoute des noms alternatifs, comme www.example.com ou une variante régionale. Le premier VirtualHost défini est le site par défaut, ce qui signifie qu'il répond aux requêtes qui ne correspondent à aucun autre. C'est un point critique : si votre premier bloc est un site important, un utilisateur qui accède à l'IP nue verra ce site. Si vous voulez un comportement dédié pour les accès orphelins, créez un VirtualHost par défaut qui renvoie une erreur 404 ou une redirection. C'est plus propre et plus prévisible.

DocumentRoot, Directory et Options

DocumentRoot pointe vers le répertoire racine du site. Le bloc <Directory> associé permet de définir les options, les règles d'accès et les comportements spécifiques à ce répertoire. On y place souvent Options -Indexes +FollowSymLinks et AllowOverride None, sauf si l'application a besoin de .htaccess. La directive Require all granted est également nécessaire pour autoriser l'accès public. En 2.4, l'oubli de cette directive produit un 403 qui surprend les administrateurs venus de la 2.2.

Journaux dédiés : error.log et access.log par site

Un journal par site simplifie le diagnostic et la surveillance. On déclare ErrorLog et CustomLog dans le bloc, en pointant vers des fichiers dédiés. Le format de log peut être personnalisé, mais le format combined est un bon point de départ. Un site sans journaux dédiés peut être difficile à isoler dans les fichiers globaux, surtout sur un serveur qui héberge plusieurs projets. Le coût de deux directives supplémentaires est négligeable, et le gain de lisibilité est immédiat.

Créer un VirtualHost HTTP pas à pas

Voici la méthode que j'utilise systématiquement, quelle que soit la distribution. Elle repose sur des fichiers séparés, activés par un mécanisme simple, et vérifiés à chaque étape. Rien de compliqué, mais une rigueur qui évite bien des erreurs.

Écrire le fichier de configuration

Sur Debian et Ubuntu, créez un fichier dans /etc/apache2/sites-available/example.com.conf. Sur RHEL et dérivés, le fichier va généralement dans /etc/httpd/conf.d/example.com.conf. Voici un exemple complet :

<VirtualHost *:80>
    ServerName example.com
    ServerAlias www.example.com
    DocumentRoot /var/www/example.com/public_html

    <Directory /var/www/example.com/public_html>
        Options -Indexes +FollowSymLinks
        AllowOverride None
        Require all granted
    </Directory>

    ErrorLog /var/www/example.com/logs/error.log
    CustomLog /var/www/example.com/logs/access.log combined
</VirtualHost>

Ce bloc est volontairement minimal. Il couvre un site statique simple. Pour une application PHP, on ajoute souvent une configuration de gestionnaire, et pour un reverse proxy, des directives ProxyPass. L'essentiel est de commencer par quelque chose qui fonctionne, puis d'enrichir progressivement. Une configuration trop ambitieuse dès le départ est plus difficile à déboguer.

Activer le site avec a2ensite ou un lien symbolique

Sur Debian et Ubuntu, la commande a2ensite example.com crée un lien symbolique dans sites-enabled. Sur RHEL, la présence du fichier dans conf.d suffit. Cette différence de philosophie peut surprendre, mais elle est facile à retenir : Debian sépare les fichiers disponibles des fichiers actifs, RHEL les active par leur simple présence. Dans les deux cas, le fichier doit être lisible par l'utilisateur root et avoir une extension .conf reconnue par Include. Un fichier mal nommé peut être ignoré sans que rien ne le signale.

Tester avec apachectl configtest

apachectl configtest ou apache2ctl configtest valide la syntaxe de l'ensemble de la configuration. Cette étape est indispensable, et pourtant souvent sautée. Si le test échoue, on ne recharge pas, et on corrige. Un rechargement sur une configuration cassée peut laisser le serveur dans un état instable, voire l'empêcher de redémarrer. C'est le genre de situation qu'on évite en deux secondes de vérification.

Recharger le service sans couper les connexions

apachectl graceful recharge la configuration sans couper les connexions en cours. C'est préférable à restart, qui interrompt les requêtes actives. En 2026, avec des sites en continu, cette nuance compte. Un graceful permet aux connexions de se terminer proprement, ce qui évite des erreurs côté utilisateurs. Pour un changement de configuration mineur, c'est le choix par défaut, et il ne coûte rien.

Passer en HTTPS : un VirtualHost sécurisé

HTTPS n'est plus une option. Les navigateurs signalent les sites non sécurisés, les moteurs de recherche les pénalisent, et les utilisateurs perdent confiance. Passer en HTTPS sur un VirtualHost est donc indispensable, et cela ajoute quelques directives à connaître. Rien d'insurmontable, mais quelques pièges à éviter.

Certificat Let's Encrypt et certificat auto-signé

Let's Encrypt est devenu le standard pour les certificats gratuits. L'outil Certbot automatise la génération et le renouvellement. Un certificat auto-signé peut dépanner en interne, mais il déclenche une alerte sur tous les navigateurs, ce qui n'est pas acceptable pour un site public. La procédure Let's Encrypt suppose un domaine résolvable et un serveur accessible. Une fois le certificat obtenu, il suffit de le référencer dans le bloc SSL. Le renouvellement automatique est configuré par Certbot et se déclenche via une tâche planifiée.

Les directives SSL obligatoires

Un bloc SSL minimal contient SSLEngine on, SSLCertificateFile et SSLCertificateKeyFile. On ajoute souvent la chaîne intermédiaire avec SSLCertificateChainFile, ou plus récemment en incluant la chaîne dans le fichier de certificat. Les protocoles et les suites de chiffrement sont définis via SSLProtocol et SSLCipherSuite. Depuis la 2.4, les valeurs par défaut sont raisonnables, mais un durcissement est recommandé pour les sites sensibles. Pour un site public, un TLS 1.2 minimum et des suites modernes suffisent.

Rediriger HTTP vers HTTPS proprement

Une fois HTTPS en place, il faut rediriger HTTP vers HTTPS. On peut le faire avec Redirect permanent / https://example.com/ dans le VirtualHost port 80, ou avec une règle RewriteRule pour plus de souplesse. Un Redirect permanent renvoie un code 301, ce qui est le bon choix pour un site durable. Pour un site en transition, un 302 temporaire peut convenir, mais il ne faut pas l'oublier. La règle de base : si vous êtes sûr de rester en HTTPS, un 301 est plus propre et mieux référencé.

Plusieurs sites sur la même machine : bonnes pratiques

Quand on gère plusieurs sites, la tentation est de tout mettre dans un seul fichier. C'est souvent une mauvaise idée, même si ça fonctionne. La séparation des fichiers facilite la lecture, la sauvegarde et la désactivation d'un site sans toucher aux autres. Une bonne structure prévient des conflits invisibles qui, sinon, se manifestent au pire moment.

Un fichier de configuration par site

Un fichier par site est la norme sur la plupart des distributions. Il permet d'activer et de désactiver un site indépendamment, d'attribuer des droits différents et de versionner au cas par cas. C'est également plus pratique pour les sauvegardes sélectives. Utilisez un nom cohérent, par exemple example.com.conf, et gardez un modèle de fichier pour en créer de nouveaux en quelques secondes. Un modèle bien fait inclut les directives communes et des commentaires pour les directives optionnelles.

Éviter le piège du premier VirtualHost par défaut

Si votre premier VirtualHost est un site important, ce site répondra aux requêtes sans Host valide. C'est rarement ce que l'on veut, mais surtout, cela masque des erreurs de configuration. Créez un premier bloc dédié, par exemple 000-default.conf, qui renvoie une 404 ou une redirection neutre. Ce bloc absorbe les requêtes orphelines et laisse vos sites réels servir uniquement leurs utilisateurs. C'est une pratique simple qui évite bien des confusions.

Isoler les journaux et les ressources

Chaque site doit avoir ses propres journaux, son propre certificat et si possible ses propres limites de ressources. Cela permet d'identifier les problèmes plus rapidement et d'éviter qu'un site ne perturbe les autres. Sur les serveurs mutualisés, l'isolation est encore plus critique. Même sur un serveur dédié, un journal par site simplifie la vie quand on consulte les événements. Et en cas de compromission, un périmètre plus étroit limite les dégâts.

Les erreurs classiques au déploiement d'un VirtualHost

Toutes les erreurs ne se valent pas, mais certaines reviennent plus souvent que d'autres. Les connaître permet de gagner du temps quand on est bloqué. Et une fois qu'on a vécu ces erreurs, on les reconnaît immédiatement.

Le site par défaut qui répond à la place du vôtre

C'est la première source de confusion quand on débute. Le premier VirtualHost déclaré reçoit toutes les requêtes qu'il ne sait pas router. Si votre site réel est déclaré après un site générique, c'est le générique qui répond. La solution est d'ordonner les blocs, ou de créer un bloc par défaut neutre en premier. Sur Debian, le fichier 000-default.conf joue souvent ce rôle, mais il faut vérifier qu'il n'est pas surchargé par d'autres fichiers. L'ordre alphabétique des fichiers dans le répertoire sites-enabled détermine l'ordre de déclaration.

403 Forbidden : permissions, Directory et Require

Un 403 signifie que le serveur refuse l'accès. Les causes possibles sont multiples : permissions Unix insuffisantes, bloc <Directory> avec une règle restrictive, directive Require manquante, ou conflit avec un fichier .htaccess. Le diagnostic doit examiner chacun de ces points. Si vous voyez un 403 sur un nouveau site, vérifiez d'abord que Require all granted est bien présent dans le bloc directory, puis les permissions. Et si un .htaccess existe, vérifiez qu'il n'introduit pas une restriction inattendue.

Le message « Could not reliably determine the server's fully qualified domain name »

Ce message apparaît au démarrage quand la directive ServerName n'est pas définie au niveau global. Il n'est pas bloquant, mais il pollue les logs. La solution est d'ajouter une directive ServerName globale, ou de la définir dans le fichier /etc/apache2/conf-available/ sur Debian. Ce message est bénin, mais il masque parfois d'autres avertissements plus importants. Autant le régler une fois pour toutes, cela simplifie la lecture des journaux.

Les modules manquants : proxy, rewrite, headers

Si un site utilise mod_rewrite et que le module n'est pas activé, les règles sont ignorées ou produisent un 404. Si un site utilise mod_proxy et que le module manque, le serveur refuse de démarrer. Il faut vérifier la liste des modules avec apachectl -M et activer ceux qui manquent. Sur Debian, a2enmod est votre ami. Sur RHEL, il faut éditer la configuration. La liste des modules indispensables dépend de ce que vous faites, mais pour un site moderne, ssl, rewrite, headers et proxy sont généralement de la partie.

Tester, valider et surveiller

Un VirtualHost correctement configuré n'est pas forcément un VirtualHost qui fonctionne. Il faut tester, puis surveiller. Les outils existent, ils sont simples, et ils évitent bien des surprises. Trois commandes suffisent pour vérifier l'essentiel.

curl -I et l'inspection des en-têtes

curl -I https://example.com affiche les en-têtes de réponse, ce qui permet de vérifier le code de statut, le type de contenu, la présence de redirections et le certificat. curl -I http://example.com sur un site HTTPS doit normalement renvoyer une redirection. Si vous voyez un 403 ou un 404, vous savez déjà où chercher. Cette commande est sous-estimée, et pourtant elle répond à la plupart des questions de diagnostic rapide. Un exemple concret vaut mille mots.

httpd -S et l'affichage des serveurs virtuels

apachectl -S affiche la liste des serveurs virtuels configurés, avec leur nom et leur ordre. C'est l'outil idéal pour vérifier qu'un site n'est pas masqué par un autre. On voit aussi les éventuels doublons et les noms d'hôte conflictuels. Si un site n'apparaît pas dans cette liste, il n'est pas chargé, ce qui restreint immédiatement la recherche. C'est une commande simple mais puissante.

Les journaux comme outil de diagnostic

Le journal d'erreurs contient les événements importants : directives invalides, erreurs de certificat, problème d'authentification. Le journal d'accès montre ce que les clients demandent et quel code est renvoyé. Ensemble, ils racontent l'histoire du site. Prenez l'habitude de les consulter après chaque modification. Et si vous ajoutez un site, testez avec un client réel depuis l'extérieur, pas seulement depuis la machine. C'est fou le nombre de problèmes réseau qui n'apparaissent qu'une fois sorti du localhost.

VirtualHost et reverse proxy : architecture moderne

Dans les architectures modernes, Apache sert souvent de frontal pour une application backend en Node.js, Python ou Java. Cette configuration repose sur mod_proxy et ses variantes. Le VirtualHost devient alors une façade, et c'est lui qui gère le TLS, la compression et parfois la mise en cache. Un rôle un peu différent, mais tout aussi important.

ProxyPass et ProxyPassReverse sur un backend applicatif

ProxyPass / http://127.0.0.1:8080/ redirige toutes les requêtes vers le backend, et ProxyPassReverse réécrit les en-têtes de redirection renvoyés par l'application. Sans cette seconde directive, certaines redirections fuient l'URL interne, ce qui peut produire des comportements bizarres. On les place généralement dans le bloc <VirtualHost>, avec éventuellement des exceptions pour les fichiers statiques. Cette configuration est devenue un standard, et la documentation officielle est bien fournie.

Mod_remoteip pour récupérer l'IP réelle des clients

Derrière un proxy ou un load balancer, Apache voit l'adresse IP du proxy, pas celle du client. Cela fausse les statistiques et certaines règles d'accès. mod_remoteip résout ce problème en lisant l'en-tête X-Forwarded-For et en substituant l'adresse du client. Il faut activer le module, configurer RemoteIPHeader X-Forwarded-For et éventuellement RemoteIPInternalProxy pour faire confiance au proxy. Une fois en place, les journaux affichent la bonne adresse et les règles d'accès fonctionnent correctement.

FAQ : les questions les plus fréquentes sur les VirtualHost

Peut-on héberger plusieurs domaines sur un seul certificat ? Oui, grâce aux certificats SAN (Subject Alternative Name) qui listent plusieurs noms. Let's Encrypt génère automatiquement ce type de certificat quand on demande plusieurs domaines. C'est pratique pour regrouper plusieurs sites sous un même certificat.

Comment ajouter un sous-domaine sans recréer un fichier ? Ajoutez simplement une ligne ServerAlias supplémentaire dans le VirtualHost existant, avec le nom du sous-domaine. Pensez à créer l'entrée DNS correspondante, puis rechargez Apache.

Un VirtualHost peut-il écouter sur un port non standard ? Oui, il suffit de déclarer l'adresse et le port dans la balise <VirtualHost>, par exemple <VirtualHost *:8443>, et d'ajouter une directive Listen correspondante au niveau global. Cela fonctionne, mais vérifiez que votre pare-feu autorise le port.

Conclusion : un VirtualHost propre, c'est une base saine pour des années

Configurer un VirtualHost, ce n'est pas un acte magique. C'est une succession de choix simples : nom, racine, permissions, journaux, SSL, redirections. Chacun de ces choix a un impact à long terme, et les erreurs du départ se paient souvent plus tard, au pire moment. En prenant le temps de structurer proprement vos fichiers, en séparant les sites et en testant avec les bons outils, vous vous donnez une base solide. En 2026, avec la généralisation du HTTPS et des architectures proxy, ce travail préparatoire est plus important que jamais. Et quand une panne survient, ce n'est pas le jour où il faut improviser. C'est le jour où l'on est content d'avoir fait les choses correctement. Alors montez votre prochain VirtualHost avec méthode, et vous verrez : ça change tout.

← molitor.photography