Running Apache with a dozen PHP versions

After showing you how to set up multiple PHP versions on a single machine, it's time to explain how to stuff all those compiled php-cgi executables into a single Apache web server instance.

Idea

Installation of FastCGI

Debian

The Debian setup is painless:

CentOS

The open source version of Redhat's operating system does not provide the fastcgi module for Apache, which is why one needs to install it by hand. It's trivial.

Assuming phpfarm is installed in /root/phpfarm, you need to chmod +x /root. Last but not least is setting up permissions for the fastcgi state files: chmod +x /var/log/httpd.

FastCGI setup

After mod_fastcgi is available, we need to prepare the FastCGI servers. Open /etc/{apache2,httpd}/{apache2,httpd}.conf and make it load conf/php-cgisetup.conf before including server.conf. Put the following lines into conf/php-cgisetup.conf:

PHP-CGI setup

For each single php version you installed with phpfarm, you need to create a file /var/www/cgi-bin/php-cgi-$version and make it executable. Example for php-cgi-5.3.2:

Activating a PHP version in a virtual host

If you followed all of the previous steps, everything is setup now and ready to be used. In your /etc/{apache2,httpd}/conf/server.conf, put the following code in each <VirtualHost ..> section that you like to switch to a certain version of PHP:


    AddHandler php-cgi .php
    Action php-cgi /cgi-bin-php/php-cgi-5.3.2
  
]]>

Conclusion

With the simple steps listed above and the help of phpfarm, you are able to test your web applications in a dozens or more PHP versions easily.

As as side note: The CGI versions of PHP are only used on the vhosts that you determine. All others are still served by mod_php that was probably setup before, making it trivially easy to keep your server's main web sites up-to date with your distribution's package manager.

FEP

Permission denied: FastCGI: can't create server … bind() failed

In this case, FastCGI is not able to create/access its socket files that are, by default, created in /var/log/apache2/fastcgi/ - because /var/log/apache2 is only root-accessible.

Either move that directory away and re-configure your apache to use the new one, or simply make the directory executable:

chmod +x /var/log/apache2
chmod +x /var/log/apache2/fastcgi

FastCGI: comm with server … aborted: idle timeout

- often in combination with FastCGI: incomplete headers (0 bytes) received from server …

By default, a timeout of 30 seconds is used for the communication between web server and FastCGI instance. This might be a bit short for long-running or complex processes. The documentation shows us how to fix that: -idle-timeout n (30 seconds).

So all we need to do is to edit conf/php-cgisetup.conf and modify the FastCgiServer lines to:

FastCgiServer /var/www/cgi-bin/php-cgi-5.3.1 -idle-timeout 120