How to Run Multiple PHP Versions Simultaneously on Ubuntu Using Apache and FastCGI


8 views

Many developers need to test their applications across different PHP versions. While Ubuntu's package manager typically provides only one PHP version, we can configure Apache with FastCGI to serve different PHP versions based on virtual hosts.

Before we begin, ensure you have:

  • Ubuntu 12.04 or later
  • Apache2 installed
  • Basic terminal skills
  • Root/sudo access

Here's how to properly set up multiple PHP versions:

1. Install Base Components

sudo apt-get update
sudo apt-get install apache2 libapache2-mod-fastcgi php5-cgi
sudo a2enmod actions fastcgi alias

2. Compile Additional PHP Versions

Using PHPFarm for compilation:

cd /usr/local/src
sudo git clone https://github.com/fpoirotte/phpfarm.git
cd phpfarm/src
sudo ./compile.sh 5.3.17
sudo ./compile.sh 5.4.7

3. Configure FastCGI Wrapper

Create wrapper scripts in /var/www/cgi-bin/:

#!/bin/bash
PHP_VERSION=$1
PHPRC="/usr/local/src/phpfarm/inst/php-${PHP_VERSION}/lib/php.ini"
export PHPRC
export PHP_FCGI_CHILDREN=4
export PHP_FCGI_MAX_REQUESTS=1000
exec "/usr/local/src/phpfarm/inst/php-${PHP_VERSION}/bin/php-cgi"

4. Virtual Host Configuration

Example configuration for PHP 5.3.17:

<VirtualHost *:80>
    ServerName 5317.localhost
    DocumentRoot /var/www
    
    <Directory "/var/www">
        Options +ExecCGI
        AddHandler php-cgi .php
        Action php-cgi /cgi-bin/php-wrapper.sh 5.3.17
    </Directory>
</VirtualHost>

5. Testing the Setup

Create a test file at /var/www/info.php:

<?php
phpinfo();
?>

If PHP files show as plain text:

  • Verify AddHandler directive is correct
  • Check file permissions on wrapper scripts
  • Ensure FastCGI module is properly loaded
  • Verify SELinux/AppArmor isn't blocking execution

For better performance:

  • Adjust PHP_FCGI_CHILDREN based on server resources
  • Consider using PHP-FPM instead of FastCGI for newer PHP versions
  • Implement proper caching mechanisms

Other methods to consider:

  • Docker containers for each PHP version
  • PHP-FPM pools with different versions
  • Cloud-based development environments

When setting up a development environment, you often need to test applications across different PHP versions. The main symptoms you're experiencing - PHP files being displayed as raw source code instead of being executed - typically indicate either:

  • Missing PHP handler configuration
  • Incorrect FastCGI setup
  • Permission issues with the FCGI scripts

First, let's verify if FastCGI is properly enabled:

apache2ctl -M | grep -i fastcgi
apache2ctl -M | grep -i suexec

You should see both fastcgi_module and suexec_module in the output.

Your current configuration needs a few adjustments:

1. FCGI Script Permissions

Ensure your FCGI scripts are executable:

sudo chmod +x /var/www/cgi-bin/php*.fcgi
sudo chown www-data:www-data /var/www/cgi-bin/php*.fcgi

2. FastCGI Configuration Update

Modify your /etc/apache2/mods-enabled/fastcgi.conf to include:

<IfModule mod_fastcgi.c>
    FastCgiIpcDir /var/lib/apache2/fastcgi
    FastCgiWrapper /usr/lib/apache2/suexec
    FastCgiConfig -idle-timeout 110 -killInterval 120 \
        -pass-header HTTP_AUTHORIZATION -autoUpdate \
        -singleThreshold 100 -updateInterval 1000
    AddHandler php-fcgi .php
    ScriptAlias /php-fcgi/ /var/www/cgi-bin/
    Action php-fcgi /php-fcgi/php5317.fcgi
</IfModule>

3. Virtual Host Configuration

Here's an optimized virtual host configuration:

<VirtualHost *:80>
    ServerName 5317.localhost
    DocumentRoot /var/www
    <Directory "/var/www">
        Options +ExecCGI +FollowSymLinks +Indexes
        AllowOverride All
        Require all granted
        AddHandler php-fcgi .php
        Action php-fcgi /php-fcgi/php5317.fcgi
    </Directory>
</VirtualHost>

For more modern setups, consider using PHP-FPM instead of FastCGI:

sudo apt-get install php5.6-fpm php7.0-fpm

Configure separate pools in /etc/php/5.6/fpm/pool.d/ and /etc/php/7.0/fpm/pool.d/.

If issues persist, check these logs:

tail -f /var/log/apache2/error.log
journalctl -xe
sudo /usr/lib/apache2/suexec -V

Here's a verified working configuration for PHP 5.6 and 7.0:

# /etc/apache2/sites-available/php56.conf
<VirtualHost *:80>
    ServerName 56.localhost
    DocumentRoot /var/www/php56
    <FilesMatch "\.php$">
        SetHandler "proxy:fcgi://127.0.0.1:9056"
    </FilesMatch>
</VirtualHost>

# /etc/php/5.6/fpm/pool.d/56.conf
[56]
listen = 127.0.0.1:9056
user = www-data
group = www-data
listen.owner = www-data
listen.group = www-data