How to select PHP version 5 and 7 per virtualhost in Apache 2.4 on Debian?
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
.
Let's start from beginning. I assume that you would prefer to use php-fpm instead of Apache module.
First install apache:
sudo apt-get update
sudo apt-get install apache2
Next install multiple PHP:
Debian 9:
Install PHP 7:
sudo apt-get install php7.0-cli php7.0-fpm php-pear libapache2-mod-fastcgi
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 PHP 5:
sudo apt-get install php5.6-cli php5.6-fpm
Debian 8:
Install PHP 5:
sudo apt-get install php5 php5-fpm php-pear libapache2-mod-fastcgi
Configure repositories:
Edit /etc/apt/sources.list
and add the following lines to the end of file:
deb http://packages.dotdeb.org jessie all
deb-src http://packages.dotdeb.org jessie all
Install GPG key:
wget https://www.dotdeb.org/dotdeb.gpg
sudo apt-key add dotdeb.gpg
sudo apt-get update
Install PHP 7:
sudo apt-get install php7.0 php7.0-fpm
Next switch from prefork and enable necessary modules:
For Debian 8:
a2dismod php5 mpm_prefork
For Debian 9:
a2dismod php7 mpm_prefork
Next for both:
a2enmod actions fastcgi alias proxy_fcgi mpm_worker
systemctl restart apache2
Change content of /etc/apache2/mods-enabled/fastcgi.conf
to the following one:
<IfModule !mod_fastcgi.c>
AddHandler fcgid-script fcg fcgi fpl
</IfModule>
<IfModule mod_fastcgi.c>
<Directory /usr/lib/cgi-bin>
Require all granted
</Directory>
</IfModule>
Now create document root folders for websites:
mkdir -p /var/www/example.com/public_html
mkdir -p /var/www/test.com/public_html
Add sys users for these websites:
sudo useradd example --home-dir /var/www/example.com
sudo useradd test --home-dir /var/www/test.com
Configure ownership:
sudo chown -R example.example /var/www/example.com
sudo chown -R test.test /var/www/test.com
For example website example.com
will use PHP 5 and website test.com
will use PHP 7.
Create configuration files for websites:
Website on PHP 5:
touch /etc/apache2/sites-available/example.com.conf
ln -s /etc/apache2/sites-available/example.com.conf /etc/apache2/sites-enabled/example.com.conf
cat /etc/apache2/sites-available/example.com.conf
<VirtualHost *:80>
ServerAdmin webmaster@localhost
ServerName example.com
ServerAlias www.example.com
DocumentRoot /var/www/example.com/public_html
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
<IfModule mod_fastcgi.c>
AddType application/x-httpd-fastphp5 .php
Action application/x-httpd-fastphp5 /php5-fcgi
Alias /php5-fcgi /usr/lib/cgi-bin/php5-fcgi-example.com
FastCgiExternalServer /usr/lib/cgi-bin/php5-fcgi-example.com -socket /var/run/php5-fpm-example.com.sock -pass-header Authorization
</IfModule>
</VirtualHost>
Website on PHP 7:
touch /etc/apache2/sites-available/test.com.conf
ln -s /etc/apache2/sites-available/test.com.conf /etc/apache2/sites-enabled/test.com.conf
cat /etc/apache2/sites-available/test.com.conf
<VirtualHost *:80>
ServerAdmin webmaster@localhost
ServerName test.com
ServerAlias www.test.com
DocumentRoot /var/www/test.com/public_html
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
<IfModule mod_fastcgi.c>
AddHandler php7-fcgi .php
Action php7-fcgi /php7-fcgi virtual
Alias /php7-fcgi /usr/lib/cgi-bin/php7-fcgi-test.com
FastCgiExternalServer /usr/lib/cgi-bin/php7-fcgi-test.com -socket /var/run/php/php7.0-fpm-test.com.sock -pass-header Authorization
</IfModule>
</VirtualHost>
Create pool configs (I used the following):
Website on PHP 5:
cat /etc/php5/fpm/pool.d/example.com.conf
[example.com]
user = example
group = example
listen = /var/run/php5-fpm-example.com.sock
listen.owner = www-data
listen.group = www-data
php_admin_value[disable_functions] = exec,passthru,shell_exec,system
php_admin_flag[allow_url_fopen] = off
pm = dynamic
pm.max_children = 5
pm.start_servers = 2
pm.min_spare_servers = 1
pm.max_spare_servers = 3
chdir = /
Website on PHP 7:
cat /etc/php/7.0/fpm/pool.d/test.com.conf
[test.com]
user = test
group = test
listen = /var/run/php/php7.0-fpm-test.com.sock
listen.owner = www-data
listen.group = www-data
php_admin_value[disable_functions] = exec,passthru,shell_exec,system
php_admin_flag[allow_url_fopen] = off
pm = dynamic
pm.max_children = 5
pm.start_servers = 2
pm.min_spare_servers = 1
pm.max_spare_servers = 3
chdir = /
Restart apache and php-fpm services:
sudo systemctl restart apache2 php5-fpm php7.0-fpm
Enjoy!