How to select PHP version 5 and 7 per virtualhost in Apache 2.4 on Debian?

Viewed 58269

Would it be possible to run PHP 7 and PHP 5 simultaneously in Apache 2.4 on Debian 9? I would like to be able to select the PHP version I wish to use per virtualhost. I believe this would be useful considering that some of my websites still use deprecated PHP features. This allows me to perform upgrades per site. How do I achieve something like this?

For example

<VirtualHost *:80>
   ServerAdmin webmaster@localhost
   ServerName mywebsite.com
   DocumentRoot /var/www/mywebsite.com

   # UsePHP 7
</virtualHost>

And

<VirtualHost *:80>
   ServerAdmin webmaster@localhost
   ServerName mywebsite2.com
   DocumentRoot /var/www/mywebsite2.com

   # UsePHP 5
</virtualHost>
2 Answers

The answer by @elvis-plesky is really detailled. But Apache suggests the usage of mod_proxy_fcgi:

With the release of apache httpd 2.4 upon an unsuspecting populace, we have gained some very neat functionality regarding apache and php: the ability to run PHP as a fastCGI process server, and address that fastCGI server directly from within apache, via a dedicated proxy module (mod_proxy_fcgi.)

Here are the steps to setup two vhosts with different PHP versions for Debian 10 using Apache's mod_proxy_fcgi and php-fpm.

Configure repositories:

sudo apt-get install apt-transport-https
sudo curl https://packages.sury.org/php/apt.gpg | apt-key add -
sudo echo 'deb https://packages.sury.org/php/ stretch main' > /etc/apt/sources.list.d/deb.sury.org.list
sudo apt-get update

Install needed PHP versions:

sudo apt-get install php5.6-cli php5.6-fpm php7.3-cli php7.3-fpm

Configure php5.6-fpm in /etc/apache2/conf-available/php5.6-fpm.conf:

<IfModule !mod_php5.c>
<IfModule proxy_fcgi_module>
    # Enable http authorization headers
    <IfModule setenvif_module>
        SetEnvIfNoCase ^Authorization$ "(.+)" HTTP_AUTHORIZATION=$1
    </IfModule>

    <FilesMatch ".+\.ph(ar|p|tml)$">
        SetHandler "proxy:unix:/run/php/php5.6-fpm.sock|fcgi://php56.localhost"
    </FilesMatch>
    # Deny access to files without filename (e.g. '.php')
    <FilesMatch "^\.ph(ar|p|ps|tml)$">
        Require all denied
    </FilesMatch>
</IfModule>
</IfModule>

Configure php7.3-fpm in /etc/apache2/conf-available/php7.3-fpm.conf:

<IfModule !mod_php7.c>
<IfModule proxy_fcgi_module>
    # Enable http authorization headers
    <IfModule setenvif_module>
        SetEnvIfNoCase ^Authorization$ "(.+)" HTTP_AUTHORIZATION=$1
    </IfModule>

    <FilesMatch ".+\.ph(ar|p|tml)$">
        SetHandler "proxy:unix:/run/php/php7.3-fpm.sock|fcgi://php73.localhost"
    </FilesMatch>
    # Deny access to files without filename (e.g. '.php')
    <FilesMatch "^\.ph(ar|p|ps|tml)$">
        Require all denied
    </FilesMatch>
</IfModule>
</IfModule>

Now add a virtual host that uses PHP 5.6:

<VirtualHost *:80>
    ServerName test-php56.localhost
    DocumentRoot "/var/www/test-php56/"
    # use php 5.6
    <FilesMatch ".+\.ph(ar|p|tml)$">
        SetHandler "proxy:unix:/run/php/php5.6-fpm.sock|fcgi://php56.localhost"
    </FilesMatch>
</VirtualHost>

And a virtual host that uses PHP 7.3:

<VirtualHost *:80>
    ServerName test-php73.localhost
    DocumentRoot "/var/www/test-php73/"
    # use php 7.3
    <FilesMatch ".+\.ph(ar|p|tml)$">
        SetHandler "proxy:unix:/run/php/php7.3-fpm.sock|fcgi://php73.localhost"
    </FilesMatch>
</VirtualHost>

Activate the correct Apache module and the configs:

sudo a2enmod proxy_fcgi
sudo a2enconf php5.6-fpm
sudo a2enconf php7.3-fpm
sudo systemctl restart apache2 php5.6-fpm php7.3-fpm

The default configuration of the FPM pools should be correct already.


Important:

This change will break old virtual hosts. You need to reconfigure all your virtual hosts and add the FilesMatch block which your project needs. For example if your project needs php 7.4 then you first need to install the fpm package:

sudo apt-get install php7.4-fpm
sudo a2enconf php7.4-fpm
sudo systemctl restart apache2 php7.4-fpm

Then add this section to your vhost config:

...
# use php 7.4
<FilesMatch ".+\.ph(ar|p|tml)$">
    SetHandler "proxy:unix:/run/php/php7.4-fpm.sock|fcgi://php74.localhost"
</FilesMatch>

Then restart apache service apache2 restart.

Related