Apache Multi Instance & Simultaneous PHP Versions
There are plenty of reasons you might want to use multiple versions of PHP on a server. In my case I needed to set up a staging server that will be used to demo various websites and web apps that have different PHP requirements.
The following diagram shows the flow the system will take to segregate the different instances.
TLDR;
All the following steps have been accumulated into a shell script that will get you going.
apache-multi-instance Shell Script
Prepare system for install
This has been tested and built on Ubuntu 16.04 LTS
sudo apt update
sudo apt install curl -y
Prepare for multiple versions of php
sudo apt install software-properties-common -y
sudo add-apt-repository ppa:ondrej/php -y
sudo apt update
Install PHP's
PHP 5.6
sudo apt install php5.6 php5.6-curl php5.6-mysql php5.6-mcrypt php5.6-gd php5.6-mbstring php5.6-zip php5.6-opcache php5.6-readline php5.6-xml -y
PHP 7.0
sudo apt install php7.0 php7.0-curl php7.0-mysql php7.0-mcrypt php7.0-gd php7.0-mbstring php7.0-zip php7.0-opcache php7.0-readline php7.0-xml -y
PHP 7.1
sudo apt install php7.1 php7.1-curl php7.1-mysql php7.1-mcrypt php7.1-gd php7.1-mbstring php7.1-zip php7.1-opcache php7.1-readline php7.1-xml -y
mcrypt deprecated after 7.1
PHP 7.2
sudo apt install php7.2 php7.2-curl php7.2-mysql php7.2-gd php7.2-mbstring php7.2-zip php7.2-opcache php7.2-readline php7.2-xml -y
PHP 7.3
sudo apt install php7.3 php7.3-curl php7.3-mysql php7.3-gd php7.3-mbstring php7.3-zip php7.3-opcache php7.3-readline php7.3-xml -y
ONE LINER
sudo apt install php5.6 php5.6-curl php5.6-mysql php5.6-mcrypt php5.6-gd php5.6-mbstring php5.6-zip php5.6-opcache php5.6-readline php5.6-xml php7.0 php7.0-curl php7.0-mysql php7.0-mcrypt php7.0-gd php7.0-mbstring php7.0-zip php7.0-opcache php7.0-readline php7.0-xml php7.1 php7.1-curl php7.1-mysql php7.1-mcrypt php7.1-gd php7.1-mbstring php7.1-zip php7.1-opcache php7.1-readline php7.1-xml php7.2 php7.2-curl php7.2-mysql php7.2-gd php7.2-mbstring php7.2-zip php7.2-opcache php7.2-readline php7.2-xml php7.3 php7.3-curl php7.3-mysql php7.3-gd php7.3-mbstring php7.3-zip php7.3-opcache php7.3-readline php7.3-xml -y
switch primary php for cli (optional)
sudo update-alternatives --set php /usr/bin/php7.3
Install Apache
We install Apache 2nd so that we can clone the php modules when we create new apache instances.
sudo apt install apache2 libapache2-mod-php -y
Use Apache Proper as the proxy
sudo a2enmod proxy
sudo a2enmod proxy_http
sudo a2enmod proxy_balancer
sudo a2enmod lbmethod_byrequests
sudo a2dissite 000-default.conf
sudo rm /etc/apache2/sites-available/000-default.conf
sudo rm /etc/apache2/sites-available/default-ssl.conf
sudo vi /etc/apache2/sites-available/proxy.conf
<VirtualHost *:80>
ProxyPreserveHost On
ProxyRequests Off
ServerAlias *.56.test.com
ProxyPass / http://127.0.0.1:8056/
ProxyPassReverse / http://127.0.0.1:8056/
</VirtualHost>
<VirtualHost *:80>
ProxyPreserveHost On
ProxyRequests Off
ServerAlias *.70.test.com
ProxyPass / http://127.0.0.1:8070/
ProxyPassReverse / http://127.0.0.1:8070/
</VirtualHost>
<VirtualHost *:80>
ProxyPreserveHost On
ProxyRequests Off
ServerAlias *.71.test.com
ProxyPass / http://127.0.0.1:8071/
ProxyPassReverse / http://127.0.0.1:8071/
</VirtualHost>
<VirtualHost *:80>
ProxyPreserveHost On
ProxyRequests Off
ServerAlias *.72.test.com
ProxyPass / http://127.0.0.1:8072/
ProxyPassReverse / http://127.0.0.1:8072/
</VirtualHost>
<VirtualHost *:80>
ProxyPreserveHost On
ProxyRequests Off
ServerAlias *.73.test.com
ProxyPass / http://127.0.0.1:8073/
ProxyPassReverse / http://127.0.0.1:8073/
</VirtualHost>
sudo a2ensite proxy.conf
sudo service apache2 start
Apache 5.6
sudo sh /usr/share/doc/apache2/examples/setup-instance php56
sudo a2dismod-php56 php7.3 php7.2 php7.1 php7.0
sudo a2enmod-php56 php5.6
sudo update-rc.d apache2-php56 defaults
sudo a2enmod-php56 vhost_alias
sudo mkdir -p /var/www/php56/test
sudo bash -c 'echo "<?php echo phpinfo(); ?>" > /var/www/php56/test/index.php'
sudo sed -i "s/.*Listen 80.*/Listen 8056/" /etc/apache2-php56/ports.conf
sudo sed -i "s/.*Listen 443.*/Listen 4056/" /etc/apache2-php56/ports.conf
sudo vi /etc/apache2-php56/sites-available/wildcard.56.test.com.conf
<VirtualHost *:8056>
ServerAlias *.56.test.com
ServerAdmin deac@sfp.net
VirtualDocumentRoot /var/www/php56/%1/
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>
sudo a2ensite-php56 wildcard.56.test.com.conf
sudo a2dissite-php56 000-default.conf
sudo rm /etc/apache2-php56/sites-available/000-default.conf
sudo rm /etc/apache2-php56/sites-available/default-ssl.conf
sudo service apache2-php56 restart
Repeat for Apache PHP 7.0
Repeat for Apache PHP 7.1
Repeat for Apache PHP 7.2
Repeat for Apache PHP 7.3
Apache 7.3
sudo sh /usr/share/doc/apache2/examples/setup-instance php73
sudo a2dismod-php73 php5.6 php7.2 php7.1 php7.0
sudo a2enmod-php73 php7.3
sudo update-rc.d apache2-php73 defaults
sudo a2enmod-php73 vhost_alias
sudo mkdir -p /var/www/php73/test
sudo bash -c 'echo "<?php echo phpinfo(); ?>" > /var/www/php73/test/index.php'
sudo sed -i "s/.*Listen 80.*/Listen 8073/" /etc/apache2-php73/ports.conf
sudo sed -i "s/.*Listen 443.*/Listen 4073/" /etc/apache2-php73/ports.conf
sudo vi /etc/apache2-php73/sites-available/wildcard.73.test.com.conf
<VirtualHost *:8073>
ServerAlias *.73.test.com
ServerAdmin deac@sfp.net
VirtualDocumentRoot /var/www/php73/%1/
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>
sudo a2ensite-php73 wildcard.73.test.com.conf
sudo a2dissite-php73 000-default.conf
sudo rm /etc/apache2-php73/sites-available/000-default.conf
sudo rm /etc/apache2-php73/sites-available/default-ssl.conf
sudo service apache2-php73 start
Testing
Run the script in a vagrant box to experiment with. The vagrant box will need to be on the same network in order to access it.
# -*- mode: ruby -*-
# vi: set ft=ruby :
Vagrant.configure("2") do |config|
config.vm.box = "ubuntu/xenial64"
config.vm.network "public_network"
config.vm.network :forwarded_port, host: 8080, guest: 80
config.vm.network :forwarded_port, host: 8056, guest: 8056
config.vm.network :forwarded_port, host: 8070, guest: 8070
config.vm.network :forwarded_port, host: 8071, guest: 8071
config.vm.network :forwarded_port, host: 8072, guest: 8072
config.vm.network :forwarded_port, host: 8073, guest: 8073
end