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
- Instead of using mod_php, mod_fastcgi is going to be utilized.
- Every single PHP version runs its own CGI server
- Configuration of used PHP version is made per virtual host.
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.