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.

Setting up permissions for the fastcgi state files is required: 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

    
      SetHandler php-cgi
    
  
]]>

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

Invalid command 'Action'

The full message is

Invalid command 'Action', perhaps misspelled or defined by a module
  not included in the server configuration

If that happens, the action module is not loaded.

$ a2enmod actions

mod_php still handles .php files

If you have both mod_php and PHP via CGI installed, the Apache module sometimes takes precedence over CGI and is used to execute the PHP files - although you specified an AddHandler php-cgi .php directive.

To fix that, SetHandler needs to be added inside the <Directory> section of your vhost:


      SetHandler php-cgi
    
  
]]>

FastCGI: failed to connect to (dynamic) server

When you get the error

No such file or directory:
FastCGI: failed to connect to (dynamic) server

then it might be that the CGI configuration is loaded too late.

To fix that, prefix the file name in conf.d with a number, e.g. 001-php-cgisetup.conf. By doing that, you ensure that Apache loads the file at first.

Thanks to Jelle Scholtalbers for the tip.

Comments? Please send an e-mail.