Mise en place d’un environnement web pour héberger plusieurs sites


Prérequis

  • Un serveur (physique, VM ou VPS) sous Debian 11 ou 12
  • Un accès root ou sudo
  • Une connexion Internet active

Étape 1 — Mise à jour du système

Avant toute installation, on met à jour l’index des paquets et les paquets existants pour partir sur une base saine et sécurisée.

apt update -y
apt upgrade -y

Étape 2 — Installation du serveur web Apache

Apache est le serveur web qui va recevoir les requêtes HTTP et les rediriger vers le bon site via les Virtual Hosts. apache2-utils fournit des outils complémentaires utiles (gestion des mots de passe, benchmarking, etc.).

apt install apache2 apache2-utils -y

Apache démarre automatiquement. On vérifie son état :

systemctl status apache2

Si Apache ne tourne pas, on le démarre manuellement :

systemctl start apache2

On active le démarrage automatique au boot :

systemctl enable apache2

On active le module de réécriture d’URL, indispensable pour Symfony et les Virtual Hosts :

a2enmod rewrite
systemctl restart apache2

Pour vérifier qu’Apache est accessible, ouvrir un navigateur et visiter :

http://ip-de-votre-serveur

La page de bienvenue Apache confirme que l’installation est réussie.


Étape 3 — Installation du serveur de base de données MariaDB

MariaDB est un système de gestion de base de données relationnelle (SGBDR) open-source, issu de MySQL. Il est plus robuste, plus sûr et offre des fonctionnalités avancées comme le moteur de stockage InnoDB.

apt install mariadb-server -y

On vérifie l’état du service :

systemctl status mariadb

Si MariaDB ne tourne pas :

systemctl start mariadb

On active le démarrage automatique au boot :

systemctl enable mariadb

Sécurisation de MariaDB

Les paramètres par défaut de MariaDB sont peu sécurisés. On les renforce avec le script dédié :

mysql_secure_installation

Répondre aux invites comme suit :

Switch to unix_socket authentication [Y/n]  → n
Change the root password? [Y/n]             → Y  (saisir un mot de passe fort)
Remove anonymous users? [Y/n]               → Y
Disallow root login remotely? [Y/n]         → Y
Remove test database and access to it? [Y/n]→ Y
Reload privilege tables now? [Y/n]          → Y

Connexion et vérification

mysql -u root -p
SHOW DATABASES;     -- liste les bases existantes
SELECT VERSION();   -- confirme la version de MariaDB
EXIT;

Création d’une base de données par site

Bonne pratique : chaque application dispose de sa propre base de données et d’un utilisateur dédié (ne jamais utiliser root pour une application). Le jeu de caractères utf8mb4 est indispensable pour Symfony (support complet de l’Unicode).

CREATE DATABASE monsite_db CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER 'monsite_user'@'localhost' IDENTIFIED BY 'mot_de_passe_fort';
GRANT ALL PRIVILEGES ON monsite_db.* TO 'monsite_user'@'localhost';
FLUSH PRIVILEGES;
EXIT;

Répéter cette opération pour chaque site hébergé.


Étape 4 — Installation de PHP 8.1

PHP est le langage côté serveur utilisé par Symfony. La version disponible par défaut sur Debian étant ancienne, on ajoute le dépôt packages.sury.org qui fournit les versions récentes de PHP.

Prérequis

Installation des outils nécessaires pour ajouter le dépôt :

apt-get install ca-certificates apt-transport-https software-properties-common wget curl lsb-release -y

Ajout du dépôt PHP

curl -sSL https://packages.sury.org/php/README.txt | bash -x
apt-get update

Installation de PHP et ses extensions

On installe PHP 8.1 et les extensions les plus couramment utilisées dans une application Symfony. D’autres extensions pourront être ajoutées ultérieurement selon les besoins.

Pour installer PHP 8.2 à la place, remplacer php8.1 par php8.2 dans la commande ci-dessous.

apt install php8.1 libapache2-mod-php8.1 php8.1-{curl,gd,intl,xml,xmlrpc,zip,mbstring,cli,common,pdo,mysql,bcmath,dev,gmp,imagick,imap,soap,sqlite3,opcache} -y

On active le module PHP dans Apache :

a2enmod php8.1
systemctl restart apache2

On vérifie la version installée :

php -v

Vérification depuis le navigateur (optionnel)

On peut créer un fichier de test temporaire pour vérifier que PHP fonctionne bien dans Apache :

echo "<?php phpinfo();" > /var/www/html/info.php

Visiter http://ip-de-votre-serveur/info.php — la page d’informations PHP doit s’afficher.

Supprimer ce fichier immédiatement après vérification (il expose des informations sensibles sur le serveur) :

rm /var/www/html/info.php

Étape 5 — Mise en place d’un site et de son Virtual Host

Un Virtual Host permet à Apache de servir plusieurs sites sur le même serveur, en associant un nom de domaine à un dossier spécifique. Chaque site a son propre fichier de configuration.

Structure des dossiers

On crée le dossier qui contiendra les fichiers de l’application :

mkdir /var/www/monsite.local

On y dépose les fichiers de l’application (décompression d’une archive, clonage Git, etc.) :

cd /var/www/monsite.local
# Exemple avec une archive :
unzip /chemin/vers/archive.zip
rm /chemin/vers/archive.zip

Permissions

On attribue les bonnes permissions pour que l’utilisateur système et Apache (www-data) puissent tous les deux lire et écrire dans le dossier sans conflit.

Remplacer user par votre nom d’utilisateur système réel.

chown -R user /var/www/monsite.local/
chgrp -R www-data /var/www/monsite.local/
chmod -R 775 /var/www/monsite.local/
find /var/www/monsite.local -type d -exec chmod g+s {} \;

Explication du SetGID (chmod g+s) : sans cette option, les fichiers créés ultérieurement (par Apache ou par l’utilisateur) héritent du groupe de leur créateur, ce qui peut provoquer des conflits de permissions. Avec le SetGID, tous les nouveaux fichiers héritent automatiquement du groupe www-data, garantissant un accès cohérent entre les deux acteurs.

Configuration du Virtual Host Apache

On crée le fichier de configuration du site :

nano /etc/apache2/sites-available/monsite.local.conf

Contenu du fichier :

<VirtualHost *:80>
    <Directory /var/www/monsite.local>
        Options Indexes FollowSymLinks
        AllowOverride All
        Require all granted
    </Directory>
    ServerAdmin webmaster@localhost
    ServerName monsite.local
    ServerAlias www.monsite.local
    DocumentRoot /var/www/monsite.local/public
    ErrorLog ${APACHE_LOG_DIR}/monsite.local-error.log
    CustomLog ${APACHE_LOG_DIR}/monsite.local-access.log combined
</VirtualHost>

Le DocumentRoot pointe vers /public/, qui est le point d’entrée de toute application Symfony. Les fichiers de log sont nommés avec le nom du site pour faciliter le débogage sur un serveur multi-sites.

On désactive le Virtual Host par défaut d’Apache et on active le nouveau :

a2dissite 000-default.conf
a2ensite monsite.local.conf

On vérifie la syntaxe de la configuration :

apache2ctl configtest
# Résultat attendu : Syntax OK

On recharge Apache pour appliquer les changements (reload est préférable à restart : il applique la configuration sans couper les connexions actives) :

systemctl reload apache2

Étape 6 — Héberger plusieurs sites (multi Virtual Hosts)

Pour chaque site supplémentaire, on répète le même processus. Apache différencie les sites grâce au ServerName de chaque Virtual Host — c’est ce qu’on appelle le name-based virtual hosting.

Pour chaque nouveau site

1. Créer le dossier et déposer les fichiers :

mkdir /var/www/site2.local
# Déposer les fichiers de l'application...

2. Appliquer les permissions :

chown -R user /var/www/site2.local/
chgrp -R www-data /var/www/site2.local/
chmod -R 775 /var/www/site2.local/
find /var/www/site2.local -type d -exec chmod g+s {} \;

3. Créer le fichier de configuration Apache :

nano /etc/apache2/sites-available/site2.local.conf
<VirtualHost *:80>
    <Directory /var/www/site2.local>
        Options Indexes FollowSymLinks
        AllowOverride All
        Require all granted
    </Directory>
    ServerAdmin webmaster@localhost
    ServerName site2.local
    ServerAlias www.site2.local
    DocumentRoot /var/www/site2.local/public
    ErrorLog ${APACHE_LOG_DIR}/site2.local-error.log
    CustomLog ${APACHE_LOG_DIR}/site2.local-access.log combined
</VirtualHost>

4. Activer le Virtual Host :

a2ensite site2.local.conf

5. Créer la base de données dédiée :

mysql -u root -p
CREATE DATABASE site2_db CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER 'site2_user'@'localhost' IDENTIFIED BY 'mot_de_passe_fort';
GRANT ALL PRIVILEGES ON site2_db.* TO 'site2_user'@'localhost';
FLUSH PRIVILEGES;
EXIT;

6. Vérifier et recharger Apache :

apache2ctl configtest
systemctl reload apache2

Étape 7 — Résolution DNS

Quand on tape une URL dans un navigateur, le DNS est le mécanisme qui fait la correspondance entre le nom de domaine (ex. monsite.local) et l’adresse IP du serveur qui héberge le site. Sans cette résolution, le navigateur ne sait pas où aller.

Les différents contextes

ContexteMéthode recommandée
Usage local (une seule machine)/etc/hosts sur sa machine
Usage en réseau local (plusieurs machines)Serveur DNS local
Production (accès Internet)DNS public chez un registrar

Méthode 1 — /etc/hosts (usage local, une seule machine)

La plus simple. On force la résolution d’un nom de domaine vers une IP directement sur la machine, sans aucun serveur DNS.

Sur le serveur :

nano /etc/hosts
127.0.0.1   monsite.local    www.monsite.local
127.0.0.1   site2.local      www.site2.local

Sur un poste client qui doit accéder au serveur, même principe mais avec l’IP du serveur :

192.168.1.50   monsite.local    www.monsite.local
192.168.1.50   site2.local      www.site2.local
  • Linux / macOS : éditer /etc/hosts avec les droits root
  • Windows : éditer C:\Windows\System32\drivers\etc\hosts en tant qu’Administrateur

⚠️ La modification doit être répétée sur chaque machine. Acceptable pour un usage solo, vite ingérable pour plusieurs personnes.


Méthode 2 — Serveur DNS local (usage en réseau local, plusieurs machines)

Dès que plusieurs machines doivent accéder aux sites, il est préférable de centraliser la résolution DNS. Les machines clientes pointent vers ce serveur DNS, et la résolution est transparente pour tout le monde.

Plusieurs solutions existent selon le niveau de complexité souhaité : Pi-hole (interface web, simple à administrer), Dnsmasq (léger, peut tourner sur le même serveur qu’Apache) ou Bind9 (solution complète pour les infrastructures avancées).

La mise en place d’un serveur DNS sort du périmètre de cette procédure — se référer à la documentation de la solution choisie.


Méthode 3 — DNS public (production, accès Internet)

Pour un site accessible sur Internet, la résolution DNS est gérée chez votre registrar (OVH, Gandi, Cloudflare…). Il suffit de créer des enregistrements de type A pointant vers l’IP publique du serveur pour chaque domaine.

Tous les enregistrements peuvent pointer vers la même IP : c’est Apache qui, via les Virtual Hosts, redirige vers le bon site selon le ServerName.

💡 En production, le passage en HTTPS est indispensable. L’outil Certbot (Let’s Encrypt) permet d’obtenir et de renouveler des certificats SSL gratuitement et s’intègre nativement avec Apache :

apt install certbot python3-certbot-apache -y
certbot --apache -d monsite.com -d www.monsite.com
certbot --apache -d site2.com -d www.site2.com

# Vérifier le renouvellement automatique
certbot renew --dry-run

Checklist — Ajouter un nouveau site

Pour chaque nouveau site, suivre cette séquence dans l’ordre :

  1. Créer le dossier /var/www/nom-du-site/ et y déposer les fichiers
  2. Appliquer les permissions (chown, chgrp, chmod, find ... chmod g+s)
  3. Créer /etc/apache2/sites-available/nom-du-site.conf
  4. Activer avec a2ensite nom-du-site.conf
  5. Créer la base de données et l’utilisateur MariaDB dédiés
  6. Ajouter la résolution DNS (selon la méthode choisie)
  7. Vérifier avec apache2ctl configtest et recharger avec systemctl reload apache2