Apache 2 : Créer des sous-domaines dynamiques

Changer dynamiquement le Document Root

23 avril 2014

Ce tutoriel a pour but d'expliquer comment changer dynamiquement le Document Root de Apache 2 en fonction du sous domaine.

Pour l'illustrer nous allons prendre un exemple :

  • web_root représente la racine web, /var/www par défaut avec Apache sur Debian.
  • http://sous_domaine1.informatix.fr aura pour Document Root : web_root/informatix.fr/sous_domaine1/www/public.
  • http://sous_domaine2.informatix.fr aura pour Document Root : web_root/informatix.fr/sous_domaine2/www/public.
  • http://sous_domaine_3.sous_domaine2.informatix.fr aura pour Document Root : web_root/informatix.fr/sous_domaine2/sous_domaine3/www/public.
  • http://sous_domaine_4.sous_domaine2.informatix.fr aura pour Document Root : web_root/informatix.fr/sous_domaine2/sous_domaine4/www/public.

L'arborescence des dossiers sera celle-là :

L'arborescence des fichiers

$ find informatix.fr -type f
informatix.fr/www/public/index.php
informatix.fr/sous_domaine1/www/public/index.php
informatix.fr/sous_domaine2/sous_domaine3/www/public/index.php
informatix.fr/sous_domaine2/www/public/index.php
informatix.fr/sous_domaine2/sous_domaine4/www/public/index.php

Tout d'abord, il faut vérifier que votre serveur DNS redirige bien tous vos sous-domaines vers votre machine.

Bind : rediriger tous les sous-domaines

*	IN	CNAME	informatix.fr.

Il faut ensuite activer le module apache qui permet de faire un document root dynamique : vhost_alias.

Activer le module vhost_alias

a2enmod vhost_alias

Maintenant place à la déclaration des virtual hosts dans /etc/apache2/site-available/informatix.fr

Tout d'abord, le vhost permettant de résoudre :
http://sous_domaine1.informatix.fr et http://sous_domaine2.informatix.fr

Sous domaine de premier niveau dynamique

<VirtualHost *:80> 
	# [subdomain1].informatix.fr : %1 vaudra [subdomain1] 
	ServerAlias *.informatix.fr 
	VirtualDocumentRoot web_root/informatix.fr/%1/www/public

	<Directory "web_root/informatix.fr/*/www/public">
		Options -Indexes +FollowSymLinks 
		AllowOverride All 
		Order allow,deny 
		Allow from all 
	</Directory>
</VirtualHost>

Dans le VirtualDocumentRoot, le sous domaine est représenté par %1. %2 vaudra "informatix" et %3 "fr". Ce système a une faille, à ce stade si vous saisissez "sous_domaine3.sous_domaine1.informatix.fr", %1 vaudra sous_domaine3, vous irez donc chercher le mauvais index.php.

Ce qui peut se traduire par une jolie erreur apache :

Apache se trompe de sous domaine

==> error.log <==
[Wed Apr 23 09:36:36 2014] [error] [client 164.248.200.42] File does not exist: web_root/informatix.fr/sous_domaine3

==> www-access.log <==
164.248.200.42 - - [23/Apr/2014:09:36:36 +0200] "GET / HTTP/1.1" 404 502

La documentation sur le module vhost_alias donne des exemples de ce qu'il est possible de faire. Exemples : %0 vaudra "sous_domaine1.informatix.fr", %2+ vaudra "informatix.fr", %2.1 vaudra "i" et %2.0 vaudra "informatix". Bien que ce ne soit pas précisé sur cette page de la documentation, d'autres directives acceptent les variables issues du ServerAlias, SetEnvIf par exemple. Notez que ce n'est malheureusement pas le cas de ErrorLog et CustomLog.

Voici une petite astuce pour faire un VirtualDocumentRoot avec un point "." dans le nom du répertoire. Supposons que nous voulons rediriger www.informatix.fr vers web_root/informatix.production/www :

VirtualDocumentRoot avec un point

# VirtualDocumentRoot web_root/%2.production/%1
service apache2 reload
[FAIL] Reloading web server config: apache2 failed!
# Et oui ! %2.[0-9]+ est une notation valide du module vhost_alias mais pas %2.production


# VirtualDocumentRoot web_root/%2.0.production/%1
service apache2 reload
[ ok ] Reloading web server config: apache2.
# Tout va bien car %2.0 est traduit par "informatix"

Pour faire fonctionner correctement les sous-domaines de second niveau :
http://sous_domaine3.sous_domaine1.informatix.fr, il faut déclarer un second vhost AU-DESSUS du premier. Si vous le déclarez en-dessous, l'étoile du premier vhost va matcher "sous_domaine3.sous_domaine1" sans problème et nous nous retrouverons dans la même situation que précédemment.

Sous domaine de second niveau dynamique

<VirtualHost *:80> 
	# [subdomain2].[subdomain1].informatix.fr : %1 vaudra [subdomain2],  %2 vaudra [subdomain1]
	ServerAlias *.*.informatix.fr 
	VirtualDocumentRoot web_root/informatix.fr/%2/%1/www/public

	<Directory "web_root/informatix.fr/*/*/www/public">
		Options -Indexes +FollowSymLinks 
		AllowOverride All 
		Order allow,deny 
		Allow from all 
	</Directory>
</VirtualHost>

Un petit reload d'Apache et c'est terminé.

A bientôt !

Par
Créateur et administrateur.

Dans la même catégorie

Docker pour les null
Git : annuler le dernier commit sans perdre ses modifications
SSHFS : monter un système de fichier avec SSH
Linux : débloquer une interface graphique gelée
Gnome 3 : changer les raccourcis clavier systèmes
Bash : sortir automatiquement du script si une variable n'est pas initialisée
Bash : sortir automatiquement du script si une commande échoue
GIT : merger 2 commits
Nginx : mettre un serveur par défaut
GIT : Afficher la branche courante dans le prompt
Couper une vidéo ou une musique sous linux
Debian / Ubuntu : installer HTTPS pour APT
Filtrer les lignes affichées par la commande tail
Transférer des fichiers sur un smartphone android sans câble USB
Comment connaitre la taille d'un dossier sous linux ?
Surveiller la sortie d'une commande avec watch
Comment lancer ou arrêter un script au démarrage de Linux ?
Comment connaître la version de mon OS Linux ?
Comment afficher le cache ARP sous Linux ?
GIT : les commandes indispensables
Comment trouver mon adresse IP publique ?
Linux : Comment configurer une adresse IP fixe ?
Comment supprimer les fichiers plus vieux qu'une date donnée en bash ?
Apache 2 : Comment changer le DocumentRoot en fonction du port ?
GIT : Comment ajouter les nouveaux fichiers automatiquement ?
Comment exécuter un script local sur une machine distante avec SSH ?
32 bits ou 64 bits ?
Ecrire dans le sudoers grâce à visudo

Commentaire(s)