blburns
3/30/2017 - 6:56 AM

Steps to get multiple versions of PHP running alongside on separate Apache virtual hosts using phpfarm

Steps to get multiple versions of PHP running alongside on separate Apache virtual hosts using phpfarm

Multiple PHP versions on Ubuntu 16.04

Steps to get multiple versions of PHP running alongside on separate Apache virtual hosts using phpfarm.
The guide uses the example of PHP v5.4.45 and v7.0.7, but installation of any version and any number of versions will be done this same way.

Prerequisites

Update the machine:

apt-get update
apt-get upgrade

Install compilation tools:

apt-get install build-essential

If it is not already there, install a LAMP server:

apt-get install lamp-server^

Install phpfarm

cd /opt
git clone git://git.code.sf.net/p/phpfarm/code phpfarm

Configure PHP

Before compiling any PHP version, setup the options you need. Options can be global or php-version specific.
In my case I will install php-5.4.45 and php-7.0.7, each with its own configuration.

cd /opt/phpfarm/src
cp options.sh custom-options-5.4.45.sh
cp options.sh custom-options-7.0.7.sh
nano /opt/phpfarm/src/options.sh

Example of my custom-options-5.4.45.sh:

#!/bin/bash
# You can override config options very easily.
# Just create a custom options file; it may be version specific:
# - custom-options.sh
# - custom-options-5.sh
# - custom-options-5.3.sh
# - custom-options-5.3.1.sh
#
# Don't touch this file here - it would prevent you to just "svn up"
# your phpfarm source code.

version=$1
vmajor=$2
vminor=$3
vpatch=$4

#gcov='--enable-gcov'
configoptions="\
--enable-bcmath \
--with-mysqli \
--with-curl \
--with-png \
--with-gd \
--enable-gd-native-ttf \
--enable-calendar \
--enable-exif \
--enable-ftp \
--enable-mbstring \
--enable-pcntl \
--enable-soap \
--with-pdo-mysql \
--enable-sockets \
--enable-sqlite-utf8 \
--enable-wddx \
--enable-zip \
--with-openssl \
--with-jpeg-dir=/usr/lib \
--with-png-dir=/usr/lib \
--with-freetype-dir=/urs/lib \
--with-zlib \
--with-gettext \
--with-mcrypt \
--with-bz2 \
--with-mysql=/usr \
$gcov"

echo $version $vmajor $vminor $vpatch

Note that the last extension refers to mysql, which does not exist for php-7.

To configure php.ini:

cp default-custom-php.ini custom-php.ini

My looks like this:

upload_max_filesize=300M
post_max_size=300M
max_file_uploads=100

date.timezone=Europe/Zurich
include_path=".:/opt/phpfarm/inst/php-$version/pear/php/"

Compile each PHP version

Illustration with php-5.4.45:

cd /opt/phpfarm/src
./compile.sh 5.4.45

The compilation will probably fail, because we lack some libraries for requested extensions.

Here are the packages corresponding to the above configuration:

apt-get install libxml2-dev libssl-dev libcurl4-openssl-dev pkg-config libbz2-dev libjpeg-dev libpng12-dev libmcrypt-dev libmysqlclient-dev

If you still get errors or if you use another configuration, here is a more exhaustive error-extensions list: #Errors encountered while trying to compile PHP7 from source

To verify the installation:

cd /opt/phpfarm/inst/bin
./php-5.4.45 --version

Notes:

  • Compilation requires a machine with more than 512 MB of RAM; it worked with 2GB.
  • To recompile a second time a php version, you have to first remove the related folders from /opt/phpfarm/inst/bin.

Install and enable FastCGI

Run:

apt-get install libapache2-mod-fastcgi apache2-suexec-pristine
a2enmod actions fastcgi suexec
service apache2 restart

Add these lines to /etc/apache2/apache2.conf before the includes:

# FastCGI configuration for multiple PHP versions
FastCgiServer /var/www/cgi-bin/php-cgi-5.4.45
FastCgiServer /var/www/cgi-bin/php-cgi-7.0.7
ScriptAlias /cgi-bin-php/ /var/www/cgi-bin/

Create the cgi directory:

mkdir /var/www/cgi-bin

Then create a cgi file for each php version. Here the /var/www/cgi-bin/php-cgi-5.4.45:

#!/bin/sh
PHPRC="/etc/php5/cgi/5.4.45/"
export PHPRC

PHP_FCGI_CHILDREN=3
export PHP_FCGI_CHILDREN

PHP_FCGI_MAX_REQUESTS=5000
export PHP_FCGI_MAX_REQUESTS

exec /opt/phpfarm/inst/bin/php-cgi-5.4.45

Make the file executable:

chmod +x /var/www/cgi-bin/php-cgi-5.4.45

Create virtual hosts

Create a config file for each virtual host, e.g.:

nano /etc/apache2/sites-available/example.local.conf
<VirtualHost *:80>
    ServerName example.local
    DocumentRoot /var/www/example.local/public/
    <Directory "/var/www/example.local">
        AddHandler php-cgi .php
        Action php-cgi /cgi-bin-php/php-cgi-5.4.45
        <FilesMatch "\.php$">
            SetHandler php-cgi
        </FilesMatch>
    </Directory>
</VirtualHost>

Do not forget to create the corresponding directories and their index files.

Enable the site:

a2ensite example.local.conf

Comment out the last line of the IfModule block in /etc/apache2/mods-available/fastcgi.conf:

<IfModule mod_fastcgi.c>
    AddHandler fastcgi-script .fcgi
    #FastCgiWrapper /usr/lib/apahce2/suexec
    #FastCgiIpcDir /var/lib/apache2/fastcgi
</IfModule>

Reload Apache configuration and restart the service:

service apache2 reload
service apache2 restart

Your hosts should now be accessible.

If you work on a local machine, do not forget to add the domain to /etc/hosts:

127.0.0.1 example.local