dimanche, 9. décembre 2012
J'ai longtemps cherché un moyen simple de gérer automatiquement mes sites sous Apache, et récemment sous Nginx.
La problématique est la suivante, j'ai créé une entrée DNS générique *.bagu.biz afin que tous les sous-domaines soient pris en compte sans que j'ai besoin de les rajouter manuellement.
Du coup, il ne me manquait plus qu'une solution afin que lorsque je créé un dossier, automatiquement le sous-domaine associé soit disponible.
Cela confère l'énorme avantage de ne jamais avoir à toucher au DNS et de pouvoir créer rapidement et facilement des sites associés au domaine principal.
Voici l’arborescence utilisée pour bagu.biz par exemple :
\www\wwwbagubiz\html
Dans lequel se trouve un dossier "www" pour www.bagu.biz et un dossier "blog" pour blog.bagu.biz.
Il y a aussi un dossier \www\wwwbagubiz\logs pour la réception des logs
Sous Apache, c'est ultra simple à faire :
<VirtualHost *:80>
ServerName www.bagu.biz
DocumentRoot /www/wwwbagubiz/html/
ServerAlias bagu.biz *.bagu.biz
VirtualDocumentRoot /www/wwwbagubiz/html/%1
RewriteEngine on
RewriteCond %{HTTP_HOST} ^bagu.biz [NC]
RewriteRule ^(.*) http://www.bagu.biz$1 [R=301,L]
<IfModule fcgid_module>
# Fcgid pmadb bug
RewriteRule .* - [E=REMOTE_USER:%{HTTP:Authorization},L]
<Files ~ "\.php$">
Options Indexes FollowSymLinks ExecCGI
AddHandler fcgid-script .php
FcgidWrapper "d:/wamp/php/php-cgi.exe -d error_log=/www/wwwbagubiz/logs/php_error.log" .php
</Files>
</IfModule>
<IfModule !fcgid_module>
php_admin_value error_log /www/wwwbagubiz/logs/php_error.log
</IfModule>
<Directory /www/wwwbagubiz/html/>
Options Indexes FollowSymLinks
AllowOverride all
Require all granted
</Directory>
</VirtualHost>
A savoir que les lignes Rewrite servent à réécrire http://bagu.biz en http://www.bagu.biz dans le cadre d'une optimisation du référencement.
Il est bon de noter aussi que je prévois l'utilisation de FCGID pour lancer PHP, mais j'ai aussi le cas ou PHP serait chargé en tant que module pour la prise en charge de l'enregistrement des logs PHP.
Maintenant, sous Nginx, c'est une autre paire de manches. Beaucoup le trouvent plus simple et/ou plus rapide, ce n'est pas mon cas...Même lors de montées en charge, le serveur Apache fait aussi bien que Nginx dans mon cas.
Je précise bien qu'il ne s'agit que de mon cas, il ne faut pas faire de généralités. En effet, sous Windows, Nginx ne peut pas profiter de php-fpm pour le lancement de scripts PHP, et c'est un très gros manque.
Nul doute que sous Linux, la différence de performances aurait été bien marquée.
Donc voici l'équivalent Nginx :
server {
listen 80;
server_name bagu.biz *.bagu.biz;
if ($host ~* ^bagu\.biz$) {
rewrite ^ http://www.bagu.biz permanent;
}
if ($host ~* ^(.*)\.bagu\.biz$) {
set $subdomain "$1";
}
root /www/wwwbagubiz/html/$subdomain;
index index.php index.html index.htm;
client_max_body_size 32M; # set maximum upload size
# deny direct access
location ~ ^/(data|config|\.ht|db_structure\.xml|README) {
deny all;
}
# default try order
location / {
try_files $uri $uri/ index.php =404;
}
# enable php
location ~* \.php$ {
try_files $uri =404;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}
Comme vous pourrez le constater, la partie de gestion des sous-domaines est infiniment plus complexe et nécessite l'utilisation du rewriting.
Cependant, cela fonctionne très bien.
A noter que si vous tentez d'utiliser Apache en même temps qu'Nginx et que vous êtes sous Windows, vous risquez de vous retrouver confronter à un bugs empêchant le lancement de scripts PHP au bout d'un certain temps.
Je n'ai, à ce jour, pas encore trouver de solution à cela (sous Linux, avec php-fpm, aucun problèmes).
J'expliquerais dans un prochain billet comment j'ai créé un service Nginx + PHP permettant un bon fonctionnement en tant que service sous Windows, le tout, redémarrable.
Avec ce système, si je créé un dossier "truc" dans \www\wwwbagubiz\html, automatiquement, http://truc.bagu.biz existera et sera exploitable, et ce sans avoir à toucher au virtualhost, ni au DNS.