Aller au contenu
medium

Apache HTTP Server : guide pratique (vhosts, TLS, performances)

28 min de lecture

Logo Apache HTTP Server

Apache HTTP Server est le serveur web historique du Web. Si vous devez héberger plusieurs sites sur un serveur, activer HTTPS, configurer un reverse proxy ou diagnostiquer une erreur 403, ce guide vous donne les recettes essentielles en quelques minutes.

Niveau : Débutant → Intermédiaire · Durée : 35-50 min

À la fin de ce guide, vous saurez :

  • Créer un Virtual Host pour héberger un site
  • Activer HTTPS avec Let’s Encrypt (Certbot)
  • Configurer un reverse proxy vers une application
  • Choisir le bon MPM (prefork, worker, event)
  • Diagnostiquer les erreurs courantes (403, 404, 500)

Apache (prononcé “a-pa-tchi”) est un serveur web qui :

  • Sert des fichiers statiques (HTML, CSS, JS, images)
  • Héberge plusieurs sites sur une seule machine (Virtual Hosts)
  • Proxyfie des applications backend (Node.js, Python, PHP)
  • Gère les modules dynamiquement (TLS, réécriture, cache)

Imaginez Apache comme un grand hôtel qui accueille des visiteurs (les requêtes HTTP) :

Concept ApacheAnalogie hôtelCe qui se passe vraiment
Virtual HostUne chambre de l’hôtelUn fichier de config qui définit un site
DocumentRootLe contenu de la chambreLe dossier où sont vos fichiers HTML/CSS/JS
ServerNameLe numéro de chambreLe domaine que le visiteur demande
ModuleUn service (spa, restaurant, coffre-fort)Une fonctionnalité qu’on active à la demande
MPML’organisation du personnelComment Apache gère les requêtes en parallèle
LogsLe registre des visiteursQui est venu, quand, et si ça s’est bien passé

Scénario : que se passe-t-il quand vous tapez une URL ?

Section intitulée « Scénario : que se passe-t-il quand vous tapez une URL ? »

Flux de traitement d'une requête HTTP par Apache

C’est comme un réceptionniste d’hôtel : le client dit “Je veux la chambre 42” (le domaine), le réceptionniste regarde son registre (les Virtual Hosts) et l’envoie au bon étage (le DocumentRoot).

📜 Pour la culture : historique d’Apache

Apache a été créé en 1995 par un groupe de développeurs qui ont pris le code du serveur NCSA HTTPd et l’ont “patché” (d’où le nom “A Patchy Server” → Apache). Il est rapidement devenu le serveur web le plus utilisé au monde.

En 2019, Nginx l’a dépassé en parts de marché, mais Apache reste très présent, notamment dans les environnements PHP traditionnels et les hébergements mutualisés.

L’architecture modulaire d’Apache et sa documentation exhaustive en font toujours un choix pertinent pour de nombreux cas d’usage.

Avant de plonger dans les commandes, assurez-vous de comprendre ces 3 concepts. Si vous les maîtrisez, tout le reste devient logique.

Question qu’on se pose tous : “Comment Apache sait quel site afficher quand j’ai plusieurs domaines ?”

Réponse : Grâce aux Virtual Hosts. Chaque VHost est un fichier de configuration qui dit :

  • ServerName : “Si le visiteur demande CE domaine…”
  • DocumentRoot : “…alors sers les fichiers de CE dossier”
# Traduction humaine de ce VHost :
# "Si quelqu'un demande www.boutique.com, envoie-lui le contenu de /var/www/boutique"
<VirtualHost *:80>
ServerName www.boutique.com # ← Le domaine
DocumentRoot /var/www/boutique # ← Le dossier des fichiers
</VirtualHost>

Question : “Pourquoi je dois ‘activer’ des trucs comme SSL ou rewrite ?”

Réponse : Apache est modulaire. Par défaut, il ne charge que le minimum pour économiser la RAM. Vous activez les fonctionnalités dont vous avez besoin :

ModuleCe qu’il faitQuand l’activer
sslHTTPSDès que vous voulez du chiffrement
rewriteRéécriture d’URLsWordPress, redirections, URLs propres
proxyReverse proxyQuand Apache est devant une app Node/Python
headersModifier les headers HTTPSécurité, cache, CORS
deflateCompression gzipToujours (gain de bande passante)

Question : “Pourquoi les tutos marchent jamais du premier coup ?”

Réponse : Parce que Debian et RHEL ont des conventions différentes :

AspectDebian/UbuntuRHEL/Rocky/Fedora
Nom du paquetapache2httpd
Nom du serviceapache2httpd
Config principale/etc/apache2/apache2.conf/etc/httpd/conf/httpd.conf
Activer un sitea2ensite monsite.confMettre le fichier dans /etc/httpd/conf.d/
Activer un modulea2enmod sslDécommenter dans les fichiers .conf
User qui exécute Apachewww-dataapache
Fenêtre de terminal
# Installer Apache
sudo apt update && sudo apt install apache2
# Démarrer et activer au boot
sudo systemctl enable --now apache2
# Vérifier le statut
sudo systemctl status apache2
# active (running) ✓

Vérification : ouvrez http://votre-ip dans un navigateur — vous devez voir la page par défaut d’Apache.

Fenêtre de terminal
sudo ufw allow 'Apache Full'
sudo ufw status
  1. Créer le répertoire et les fichiers

    Fenêtre de terminal
    sudo mkdir -p /var/www/monsite
    echo '<h1>Mon site Apache</h1>' | sudo tee /var/www/monsite/index.html
    # Permissions : propriétaire = www-data (Debian) ou apache (RHEL)
    sudo chown -R www-data:www-data /var/www/monsite # Debian
    # sudo chown -R apache:apache /var/www/monsite # RHEL
  2. Créer le Virtual Host

    Fenêtre de terminal
    sudo tee /etc/apache2/sites-available/monsite.conf << 'EOF'
    <VirtualHost *:80>
    ServerName monsite.local
    DocumentRoot /var/www/monsite
    <Directory /var/www/monsite>
    Options -Indexes +FollowSymLinks
    AllowOverride None
    Require all granted
    </Directory>
    ErrorLog ${APACHE_LOG_DIR}/monsite-error.log
    CustomLog ${APACHE_LOG_DIR}/monsite-access.log combined
    </VirtualHost>
    EOF
  3. Activer le site et tester

    Fenêtre de terminal
    # Activer le site
    sudo a2ensite monsite.conf
    # Désactiver le site par défaut (optionnel)
    sudo a2dissite 000-default.conf
    # Tester la configuration
    sudo apache2ctl configtest
    # Syntax OK
    # Recharger Apache
    sudo systemctl reload apache2
  4. Vérifier

    Fenêtre de terminal
    curl -I http://localhost
    # HTTP/1.1 200 OK

Apache peut héberger plusieurs sites sur la même machine grâce aux Name-based Virtual Hosts.

Quand votre navigateur envoie une requête HTTP, il inclut un header Host: qui contient le domaine demandé :

GET /index.html HTTP/1.1
Host: www.site1.com ← C'est ça qu'Apache utilise
User-Agent: Mozilla/5.0...

Apache lit ce header et cherche le Virtual Host correspondant. C’est comme avoir plusieurs boîtes aux lettres sur une même adresse postale : le facteur (Apache) regarde le nom sur l’enveloppe (header Host) pour savoir dans quelle boîte déposer le courrier.

Imaginons que vous avez :

  • www.boutique.com → votre e-commerce
  • www.blog.com → votre blog

Les deux domaines pointent vers la même IP (votre serveur). Comment Apache fait la différence ?

Architecture Virtual Hosts Apache : plusieurs sites sur un serveur

# /etc/apache2/sites-available/site1.conf (Debian)
# ou /etc/httpd/conf.d/site1.conf (RHEL)
<VirtualHost *:80>
ServerName www.site1.com
ServerAlias site1.com
DocumentRoot /var/www/site1
<Directory /var/www/site1>
Options -Indexes +FollowSymLinks
AllowOverride None
Require all granted
</Directory>
ErrorLog ${APACHE_LOG_DIR}/site1-error.log
CustomLog ${APACHE_LOG_DIR}/site1-access.log combined
</VirtualHost>
/etc/apache2/sites-available/site2.conf
<VirtualHost *:80>
ServerName www.site2.com
ServerAlias site2.com
DocumentRoot /var/www/site2
<Directory /var/www/site2>
Options -Indexes +FollowSymLinks
AllowOverride None
Require all granted
</Directory>
ErrorLog ${APACHE_LOG_DIR}/site2-error.log
CustomLog ${APACHE_LOG_DIR}/site2-access.log combined
</VirtualHost>
Sans HTTPSAvec HTTPS
Données en clair sur le réseauTout est chiffré
Google pénalise votre SEOBonus de classement
Navigateurs affichent “Non sécurisé”Cadenas vert
Vulnérable au man-in-the-middleCommunication sécurisée
  1. Installer Certbot

    Fenêtre de terminal
    sudo apt install certbot python3-certbot-apache
  2. Obtenir le certificat

    Fenêtre de terminal
    sudo certbot --apache -d exemple.com -d www.exemple.com

    Certbot :

    • Vérifie que vous contrôlez le domaine
    • Obtient un certificat Let’s Encrypt
    • Modifie automatiquement votre Virtual Host
    • Configure la redirection HTTP → HTTPS
  3. Vérifier le renouvellement automatique

    Fenêtre de terminal
    sudo certbot renew --dry-run

    Le timer systemd gère le renouvellement automatique (environ 30 jours avant expiration).

Après Certbot, ajoutez ces directives pour une configuration TLS moderne :

<VirtualHost *:443>
ServerName exemple.com
DocumentRoot /var/www/exemple
SSLEngine On
SSLCertificateFile /etc/letsencrypt/live/exemple.com/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/exemple.com/privkey.pem
# TLS moderne uniquement
SSLProtocol all -SSLv3 -TLSv1 -TLSv1.1
SSLCipherSuite ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256
SSLHonorCipherOrder off
# HSTS (activer seulement quand HTTPS fonctionne)
Header always set Strict-Transport-Security "max-age=31536000"
<Directory /var/www/exemple>
Options -Indexes +FollowSymLinks
AllowOverride None
Require all granted
</Directory>
</VirtualHost>
# Redirection HTTP → HTTPS
<VirtualHost *:80>
ServerName exemple.com
Redirect permanent / https://exemple.com/
</VirtualHost>

Un reverse proxy est un intermédiaire entre les visiteurs et vos applications. Au lieu que votre app Node.js ou Python écoute directement sur le port 80, c’est Apache qui reçoit les requêtes et les transmet à votre app.

Apache reverse proxy : comparaison avec et sans

QuestionRéponse
”Mon app Node écoute sur 3000, comment la mettre sur le port 80 ?”Le reverse proxy redirige 80 → 3000
”Je veux du HTTPS mais mon framework ne le gère pas bien”Apache gère TLS, votre app reste en HTTP local
”J’ai 3 apps sur un serveur, comment les exposer ?”Un VHost par app, chacun proxyfie vers un port différent
”Je veux des logs Apache standardisés”Le proxy loggue tout, votre app n’a pas à s’en occuper
Sans reverse proxyAvec reverse proxy (Apache)
Votre app écoute sur le port 80Apache écoute sur 80/443, votre app sur 3000
Pas de HTTPS (ou config manuelle)Apache gère TLS
Une seule app par serveurPlusieurs apps sur le même serveur
Fenêtre de terminal
sudo a2enmod proxy proxy_http proxy_balancer lbmethod_byrequests
sudo systemctl restart apache2
<VirtualHost *:80>
ServerName api.exemple.com
ProxyPreserveHost On
ProxyPass / http://127.0.0.1:3000/
ProxyPassReverse / http://127.0.0.1:3000/
# Headers pour que le backend connaisse le client réel
RequestHeader set X-Forwarded-Proto "http"
RequestHeader set X-Real-IP "%{REMOTE_ADDR}s"
ErrorLog ${APACHE_LOG_DIR}/api-error.log
CustomLog ${APACHE_LOG_DIR}/api-access.log combined
</VirtualHost>
<VirtualHost *:80>
ServerName exemple.com
DocumentRoot /var/www/frontend
# L'API sur /api/*
ProxyPass /api/ http://127.0.0.1:3000/
ProxyPassReverse /api/ http://127.0.0.1:3000/
# Le reste en statique
<Directory /var/www/frontend>
Options -Indexes +FollowSymLinks
AllowOverride None
Require all granted
</Directory>
</VirtualHost>

MPM signifie Multi-Processing Module. C’est la façon dont Apache gère les requêtes en parallèle.

Question fréquente : “Pourquoi Apache est lent / consomme trop de RAM ?”

Réponse courte : Vous utilisez probablement le mauvais MPM.

MPMAnalogieComment ça marche
preforkUn serveur au restaurant par table1 processus par requête. Simple mais gourmand en RAM.
workerPlusieurs serveurs, chacun gère plusieurs tablesProcessus + threads. Plus efficace.
eventworker + un maître d’hôtel qui gère l’attenteComme worker, mais gère mieux les connexions keepalive.

Comparaison des MPM Apache : prefork vs event

SituationMPM recommandéPourquoi
PHP avec mod_phppreforkmod_php n’est pas thread-safe
PHP-FPM / proxy_fcgieventMeilleure gestion des connexions
Reverse proxyeventGère mieux les connexions keepalive
Beaucoup de connexionseventPlus efficace en mémoire
Compatibilité maximalepreforkFonctionne avec tout
Fenêtre de terminal
# Désactiver prefork, activer event
sudo a2dismod mpm_prefork
sudo a2enmod mpm_event
sudo systemctl restart apache2

Réduit la taille des réponses de 60-80% :

<IfModule mod_deflate.c>
AddOutputFilterByType DEFLATE text/html text/plain text/xml
AddOutputFilterByType DEFLATE text/css application/javascript
AddOutputFilterByType DEFLATE application/json application/xml
</IfModule>
Fenêtre de terminal
sudo a2enmod deflate
sudo systemctl restart apache2

Pour les fichiers statiques :

<IfModule mod_expires.c>
ExpiresActive On
ExpiresByType image/jpeg "access plus 1 year"
ExpiresByType image/png "access plus 1 year"
ExpiresByType text/css "access plus 1 month"
ExpiresByType application/javascript "access plus 1 month"
</IfModule>
# Dans /etc/apache2/conf-available/security.conf (Debian)
# ou /etc/httpd/conf.d/security.conf (RHEL)
# Masquer la version d'Apache
ServerTokens Prod
ServerSignature Off
# Headers de sécurité
<IfModule mod_headers.c>
Header always set X-Content-Type-Options "nosniff"
Header always set X-Frame-Options "SAMEORIGIN"
Header always set Referrer-Policy "strict-origin-when-cross-origin"
</IfModule>
# Désactiver le listing des répertoires (global)
<Directory />
Options -Indexes
</Directory>
Fenêtre de terminal
sudo a2enmod headers
sudo a2enconf security
sudo systemctl restart apache2
<Directory /var/www/monsite>
<LimitExcept GET POST HEAD>
Require all denied
</LimitExcept>
</Directory>

Quand Apache ne fonctionne pas, suivez toujours cet ordre. 90% des problèmes se résolvent en moins de 2 minutes :

Méthode de diagnostic Apache en 4 étapes

Toujours tester la configuration avant de recharger :

Fenêtre de terminal
# Debian/Ubuntu
sudo apache2ctl configtest
# RHEL/Rocky
sudo httpd -t

Pourquoi ? Si votre config a une erreur de syntaxe et que vous faites systemctl reload, Apache va planter. En testant avant, vous évitez de casser un serveur en production.

Fenêtre de terminal
# 1. Apache tourne-t-il ?
systemctl status apache2 # ou httpd
# 2. La config est-elle valide ?
sudo apache2ctl configtest # ou httpd -t
# 3. Quels modules sont actifs ?
apache2ctl -M # ou httpd -M
# 4. Logs d'erreur récents
sudo tail -20 /var/log/apache2/error.log # Debian
sudo tail -20 /var/log/httpd/error_log # RHEL
# 5. Quel Virtual Host répond ?
sudo apache2ctl -S # ou httpd -S

Ce que ça veut dire : Apache a trouvé le fichier, mais refuse de le servir.

Causes possibles (dans l’ordre de fréquence) :

  1. Permissions fichiers : Apache (user www-data ou apache) ne peut pas lire le fichier

    Fenêtre de terminal
    # Vérifier
    ls -la /var/www/monsite/
    # Corriger
    sudo chown -R www-data:www-data /var/www/monsite # Debian
    sudo chmod -R 755 /var/www/monsite
  2. Directive Require all denied dans la config (ou absence de Require all granted)

  3. SELinux (RHEL/Rocky) bloque l’accès

    Fenêtre de terminal
    # Vérifier
    getenforce
    # Si "Enforcing", corriger les contextes :
    sudo restorecon -Rv /var/www/monsite

Ce que ça veut dire : Apache ne trouve pas le fichier demandé.

Causes possibles :

  • DocumentRoot incorrect : le dossier dans le VHost ne correspond pas à la réalité
  • Fichier absent : index.html n’existe pas
  • Typo dans l’URL : /inex.html au lieu de /index.html
Fenêtre de terminal
# Vérifier que le fichier existe vraiment
ls -la /var/www/monsite/index.html

Ce que ça veut dire : Apache a planté en essayant de répondre.

Causes possibles :

  • Erreur dans .htaccess : syntaxe invalide, module manquant
  • Script PHP/Python qui plante

Solution : Toujours regarder le log d’erreur :

Fenêtre de terminal
sudo tail -30 /var/log/apache2/error.log

Ce que ça veut dire : Apache affiche la page par défaut au lieu de votre site.

Causes possibles :

  • VHost non activé : a2ensite monsite.conf oublié
  • ServerName incorrect : ne correspond pas au domaine demandé
Fenêtre de terminal
# Voir quel VHost répond pour quel domaine
apache2ctl -S
ErreurCause probableSolution
403 ForbiddenPermissions ou Require all deniedVoir ci-dessus
404 Not FoundDocumentRoot ou fichier absentVérifier le chemin
500 Internal Server Error.htaccess ou script casséRegarder error.log
”It works”VHost non activéa2ensite + apache2ctl -S
AH00558: Could not reliably…ServerName global absentAjouter ServerName localhost
Fenêtre de terminal
# 1. Vérifier les permissions
ls -la /var/www/monsite/
# Le user www-data (ou apache) doit pouvoir lire
# 2. Vérifier la config Directory
grep -A5 "Directory /var/www/monsite" /etc/apache2/sites-enabled/*
# 3. SELinux (RHEL) ?
getenforce
# Si "Enforcing" :
sudo setenforce 0 # Tester temporairement
# Si ça marche, corriger les contextes :
sudo restorecon -Rv /var/www/monsite
CommandeDescription
a2ensite monsite.confActiver un site
a2dissite monsite.confDésactiver un site
a2enmod rewriteActiver un module
a2dismod rewriteDésactiver un module
apache2ctl configtestTester la configuration
apache2ctl -MLister les modules actifs
apache2ctl -SLister les Virtual Hosts
CommandeDescription
httpd -tTester la configuration
httpd -MLister les modules actifs
httpd -SLister les Virtual Hosts
ÉlémentDebian/UbuntuRHEL/Rocky
Config principale/etc/apache2/apache2.conf/etc/httpd/conf/httpd.conf
Sites disponibles/etc/apache2/sites-available/
Sites activés/etc/apache2/sites-enabled//etc/httpd/conf.d/
Modules/etc/apache2/mods-available//etc/httpd/conf.modules.d/
Logs/var/log/apache2//var/log/httpd/
DocumentRoot par défaut/var/www/html/var/www/html
DirectiveDescription
ServerName www.exemple.comNom du site
ServerAlias exemple.comAlias (sans www)
DocumentRoot /var/www/siteRacine des fichiers
Options -IndexesDésactiver le listing
AllowOverride NoneIgnorer les .htaccess
Require all grantedAutoriser l’accès
ErreurConséquenceSolution
AllowOverride All partoutPerf dégradée, sécurité réduiteAllowOverride None + config centrale
Oublier a2enmod sslHTTPS ne fonctionne pasActiver le module avant Certbot
Permissions 777Faille de sécurité majeure755 pour dossiers, 644 pour fichiers
Confondre Debian et RHELChemins et commandes différentsVérifier la distribution
SELinux non configuré403 mystérieux sur RHELsetsebool -P httpd_can_network_connect 1
mod_php + MPM eventCrash ou comportement erratiqueUtiliser prefork avec mod_php
  1. apache2ctl configtest : toujours tester avant de recharger
  2. Virtual Host = un site, avec son ServerName et DocumentRoot
  3. AllowOverride None : la règle en production
  4. MPM event : pour les perfs (sauf mod_php)
  5. Certbot : HTTPS en une commande
  6. Logs : votre meilleur ami pour débugger

Ce site vous est utile ?

Sachez que moins de 1% des lecteurs soutiennent ce site.

Je maintiens +700 guides gratuits, sans pub ni tracing. Aujourd'hui, ce site ne couvre même pas mes frais d'hébergement, d'électricité, de matériel, de logiciels, mais surtout de cafés.

Un soutien régulier, même symbolique, m'aide à garder ces ressources gratuites et à continuer de produire des guides de qualité. Merci pour votre appui.