Apache 2.4 / PHP, création et automatisation des virtual hosts avec le module des macros (mod_macro)

Introduction

Apache 2.2 est en End of Life depuis Juillet 2017, il est temps de passer à Apache 2.4 pour les retardataires comme l'auteur de cet article.

La grande nouveauté d'Apache 2.4 parmi bien d'autres : le support du protocole HTTP 2 depuis la version 2.4.12, protocole insufflé très largement par le protocole expérimental SPDY (SPeeDY) développé par Google pour combler les lacunes en performances du très vieux protocole HTTP 1.

L'utilisation du protocole HTTP 2 n'est pas le sujet de cet article.

La grande nouveauté d'Apache 2.4 est la possibilité dans les fichiers de configuration de définir des variables avec l'instruction Define, d'utiliser des expressions if, elseif, else, expr et de programmer des macros avec le nouveau module mod_macro.

Voyons comment mettre à profit les fonctionnalités de la version 2.4 pour industrialiser les hôtes virtuels (virtual hosts) en local sous windows. Les virtual hosts sont créés ici dynamiquement avec le module mod_macro.

Le contexte est identique à celui décrit pour Apache 2.2 dans l'article Apache 2.2 et PHP sous Windows, environnements de développement multiples avec les virtual hosts : chaque virtual host dispose de sa propre version de PHP à des fins de développement, de migration, de tests de non régression, de debug...

Environnement hôte virtuel Description Version de PHP
www.sqlpac.dvt Développement PHP 7.3.4
www.sqlpac.ppd Préproduction PHP 7.3.1
www.sqlpac.dbg Debug production PHP 7.0

Installation d'Apache 2.4

La version d'Apache 2.4.39 avec OpenSSL 1.0.2r est téléchargée depuis le site Apache Haus (Downloads - Apache 2.4 Server Binaries).

Il s'agit d'une archive zip (httpd-2.4.39-o102r-x86-vc14.zip) décompressée dans le répertoire D:\software\apache\apache-2.4 qui sera appelé %APACHE_HOME% dans la suite de cet article.

En éditant le fichier de configuration httpd.conf, il y a déjà un aperçu sur la façon d'utiliser des variables avec Apache 2.4 (${SRVROOT}) :

%APACHE_HOME%\conf\httpd.conf
Define SRVROOT "/Apache24"
ServerRoot "${SRVROOT}"
...
DocumentRoot "${SRVROOT}/htdocs"
<Directory "${SRVROOT}/htdocs">
...
    #
    # Controls who can get stuff from this server.
    #
    Require all granted
</Directory>

Éditer le fichier httpd.conf afin qu'il reflète le répertoire d'installation d'Apache 2.4 pour la variable ${SRVROOT}.

%APACHE_HOME%\conf\httpd.conf
Define SRVROOT "D:/software/apache/apache-2.4"

Installation et paramétrage du module fcgid_module

Pendant que l'installation est en cours, autant en profiter pour installer également, si il n'est pas présent, le module fcgid (Fast CGI), module nécessaire à PHP et livré à part. Il est également disponible sur le site Apache Haus (Downloads - Modules for Apache 2.4.x VC14 - Mod FCGID 2.3.9a for Apache 2.4.x x64).

Il s'agit d'une archive zip contenant 2 fichiers à copier dans les répertoires ci-dessous :

httpd-fcgid.conf %APACHE_HOME%\conf\extra
mod_fcgid.so %APACHE_HOME%\modules

Le module fcgid est ajouté au serveur Apache en modifiant le fichier de configuration httpd.conf avec les directives ci-dessous :

%APACHE_HOME%\conf\httpd.conf
# AJOUT FCGID
#
LoadModule fcgid_module modules/mod_fcgid.so
Include conf/extra/httpd-fcgid.conf

Commenter les directives de la section "Global Config Example" dans le fichier %APACHE_HOME%/conf/extra/httpd-fcgid.conf car elles implémentent une configuration globale au serveur par défaut, ce qui ne sera pas le cas ici, la configuration sera réalisée par virtual host.

%APACHE_HOME%\conf\extra\httpd-fcgid.conf
# Global Config Example
# Comment out next 4 lines to use per-Directory or per-VirtualHost configuration
#  <Files ~ "\.php$">
#    Options ExecCGI
#    AddHandler fcgid-script .php
#    FcgidWrapper "C:/php/php-cgi.exe" .php
#  </Files>

Activation du module des macros (macro_module)

Les virtual hosts sont créés dynamiquement au démarrage grâce au module des macros (macro_module), nouveauté d'Apache 2.4. Il faut activer ce module dans le fichier httpd.conf.

%APACHE_HOME%\conf\httpd.conf
LoadModule macro_module modules/mod_macro.so

Création du service Windows pour Apache 2.4

Pour définir un service Windows appelé "Apache 2.4" et associé à cette installation, dans une fenêtre DOS ouverte avec les droits Administrateur lancer la commande :

%APACHE_HOME%/bin/httpd.exe -k install -n "Apache 2.4"

Avec cette commande, les erreurs éventuelles de syntaxe sont détectées :

Installing the 'Apache 2.4' service
The 'Apache 2.4' service is successfully installed.
Testing httpd.conf....
Errors reported here must be corrected before the service can be started.
httpd.exe: Syntax error on line 39 of D:/software/apache/apache-2.4/conf/httpd.conf: ServerRoot must be a valid directory

Le service tente de démarrer, et bien entendu si le serveur Apache 2.2 est encore en route, une erreur d'attachement du port 80 est levée.

(OS 10048) ...  : AH00072: make_sock: could not bind to address [::]:80
(OS 10048) ...  : AH00072: make_sock: could not bind to address 0.0.0.0:80

Une fois le service démarré avec succès, ouvrir l'adresse http://localhost dans un navigateur pour tester.

Référencement des domaines virtuels dans le fichier hosts

Afin que les domaines virtuels www.sqlpac.dvt, www.sqlpac.ppd... soient résolus, éditer le fichier hosts de la machine Windows pour associer les domaines à l'IP locale 127.0.0.1. Ce fichier est dans le répertoire C:\Windows\system32\drivers\etc et il doit être ouvert avec les droits administrateur pour pouvoir le mettre à jour. Éditer ce fichier avec précaution, il est sensible pour l'OS.

C:\Windows\system32\drivers\etc\hosts
# localhost name resolution is handled within DNS itself.
#	127.0.0.1       localhost
#	::1             localhost

127.0.0.1	www.sqlpac.dvt
127.0.0.1	www.sqlpac.ppd
127.0.0.1	www.sqlpac.dbg

Ne pas choisir l'extension .dev, avec Apache, cette extension finit en erreur 408 (Timeout).

Une simple commande ping confirme la résolution des domaines virtuels. Il se peut qu'un redémarrage de la machine soit nécessaire.

C:\Users\sqlpac> ping www.sqlpac.dvt
Envoi d’une requête 'ping' sur www.sqlpac.dvt [127.0.0.1] avec 32 octets de données :
Réponse de 127.0.0.1 : octets=32 temps<1ms TTL=128
Réponse de 127.0.0.1 : octets=32 temps<1ms TTL=128
...

Définition des virtual hosts par macros

Avec Apache 2.2, il fallait définir explicitement les virtual hosts sans pouvoir utiliser de variables afin d'automatiser le processus. Grâce aux macros d'Apache 2.4, tout peut être industrialisé.

Avec Apache 2.2, pour définir le virtual host www.sqlpac.ppd

<VirtualHost *:80>
        
    DocumentRoot "D:/www/preproduction"
    ServerName sqlpac.ppd
    ServerAlias www.sqlpac.ppd
    ErrorLog "logs/www.sqlpac.ppd-error.log"
    CustomLog "logs/www.sqlpac.ppd-access.log" common
    
    Alias /articles "D:/www/preproduction/referentiel/docs"
    
    <Directory "D:/www/preproduction">
        Options Indexes FollowSymLinks
        Options +ExecCGI
        AllowOverride All
        Order allow,deny
        Allow from all
    </Directory>
    
</VirtualHost>

Avec Apache 2.4, cette définition peut désormais être variabilisée et prise en charge par une macro (macro appelée ici VHost). La macro peut être programmée dans le fichier de configuration httpd.conf mais elle peut tout aussi l'être dans un autre fichier de configuration sourcé au démarrage du serveur avec la directive Include.

%APACHE_HOME%\conf\httpd.conf
<Macro VHost $domain $port $docroot>
  <VirtualHost *:$port>

    DocumentRoot "$docroot"
    ServerName $domain
    ServerAlias www.$domain
    ErrorLog "logs/www.$domain-error.log"
    CustomLog "logs/www.$domain-access.log" common
    
    Alias /pubs $docroot/referentiel/docs
    
    <Directory "$docroot>";
        Options -Indexes +FollowSymLinks
        Options +ExecCGI
        AllowOverride All
        # Apache 2.4
        Require all granted
        # Apache 2.2
        # Order allow,deny
        # Allow from all
    </Directory>

  </VirtualHost>
</Macro>

Les noms des macros sont insensibles à la casse, en revanche les variables définies dans les macros le sont.

Les virtual hosts www.sqlpac.dvt, www.sqlpac.ppd et www.sqlpac.dbg sont alors définis en cascade avec les directives ci-dessous dans le fichier httpd.conf :

%APACHE_HOME%/conf/httpd.conf
<Macro VHost $domain $port $docroot>
  <VirtualHost *:$port>

    DocumentRoot "$docroot"
    ...
    
  </VirtualHost>
</Macro>    

Use VHost sqlpac.dvt 80 "D:\www\dev"
Use VHost sqlpac.ppd 80 "D:\www\preproduction"
Use VHost sqlpac.dbg 80 "D:\www\productiondbg"

UndefMacro VHost

Personnalisation de la version de PHP par virtual host avec la macro

La macro définissant les virtual hosts peut alors être étendue pour ajouter la version de PHP propre à chaque virtual host.

Chaque hôte virtuel utilisera les versions de PHP ci-dessous.

Domaine virtual host Version de PHP Répertoire
www.sqlpac.dvt 7.3.4 D:\software\scripts\php-7.3.4
www.sqlpac.ppd 7.3.1 D:\software\scripts\php-7.3.1
www.sqlpac.dbg 7.0 D:\software\scripts\php-7.0

La variable globale ${PHPHOME} qui identifie le répertoire des distributions PHP (D:\software\scripts) est d'abord définie dans le fichier de configuration httpd.conf.

La macro initialise ensuite les paramètres FastCGI (FcgidInitialEnv, AddHandler fcgid-script, FcgidWrapper) pour chaque virtual host en s'appuyant sur la variable globale ${PHPHOME} et le paramètre ${phpversion} donné en entrée de la macro VHost.

%APACHE_HOME%\conf\httpd.conf
Define PHPHOME "D:/software/scripts"

<Macro VHost $domain $port $docroot $phpversion>
  <VirtualHost *:$port>

    FcgidInitialEnv PHPRC "D:/software/scripts/php-$phpversion"
    AddHandler fcgid-script .php .inc .html
    FcgidWrapper "${PHPHOME}/php-$phpversion/php-cgi.exe" .php
    FcgidWrapper "${PHPHOME}/php-$phpversion/php-cgi.exe" .inc
    FcgidWrapper "${PHPHOME}/php-$phpversion/php-cgi.exe" .html

    DocumentRoot "$docroot"
    ServerName $domain
    ServerAlias www.$domain
    ErrorLog "logs/www.$domain-error.log"
    CustomLog "logs/www.$domain-access.log" common
    
    Alias /pubs $docroot/referentiel/docs
    
    <Directory "$docroot>";
        Options -Indexes +FollowSymLinks
        Options +ExecCGI
        AllowOverride All
        # Apache 2.4
        Require all granted
    </Directory>

  </VirtualHost>
</Macro>

Les virtual hosts sont alors tout simplement instanciés avec les directives suivantes :

%APACHE_HOME%\conf\httpd.conf
Define PHPHOME "D:/software/scripts"

<Macro VHost $domain $port $docroot $phpversion>
  <VirtualHost *:$port>
    ...
  </VirtualHost>
</Macro>    

Use VHost sqlpac.dvt 80 "D:\www\dev" "7.3.4"
Use VHost sqlpac.ppd 80 "D:\www\preproduction" "7.3.1"
Use VHost sqlpac.dbg 80 "D:\www\productiondbg" "7.0"

UndefMacro VHost

Tests

Redémarrer le serveur Apache, c'est terminé, sauf si des erreurs de syntaxe se sont glissées par ci par là, consulter les fichiers de log d'Apache dans ce cas.

Pour les tests, créér un fichier phpinfo.html avec le code ci-dessous :

phpinfo.html
<!DOCTYPE html>

<html>
<head>
    <title>PHP Info</title>
</head>

<body>
    <p>Informations PHP - Script PHP</p>

<?php  phpinfo(); ?>

</body>
</html>

Copier ce fichier dans un répertoire de chaque virtual host, la version de PHP utilisée est confirmée avec la fonction phpinfo().

http://www.sqlpac.dvt/phpinfo.html PHP Version 7.3.4 ...
http://www.sqlpac.ppd/phpinfo.html PHP Version 7.3.1 ...
http://www.sqlpac.dbg/phpinfo.html PHP Version 7.0.10 ...

Conclusion

Pour administrer les serveurs Apache version 2.2, des scripts shell, awk... ont été d'un grand secours pour générer les fichiers de configurations nécessaires (virtual hosts...).

Sans même avoir abordé dans cet article les expressions conditionnelles if, elseif, else, expr, on entraperçoit d'un point de vue administration l'utilité puissante du nouveau module des macros avec Apache 2.4.