Running PHP4 & PHP5 concurrently

On 1 Apache server using FastCGI

Alex Dean

Background

Setup

This is the testing setup I put together :

A note on binaries

Install Apache 2.0.59

shell> cd /usr/local/src/apache-2.0.59

# Nothing too special.  Enable shared-object support and
# use the prefork module recommended by php.net
shell> ./configure 
          --prefix=/usr/local/apache-2.0.59 
          --enable-so
          --with-mpm=prefork

shell> make
shell> make install

http://httpd.apache.org/docs/2.0/install.html

Install PHP 4.4.4

shell> ./configure
          --prefix=/usr/local/php-4.4.4
          --with-apxs2=/usr/local/apache-2.0.59/bin/apxs
          --enable-memory-limit
          --with-mysql
shell> make
shell> make install

You might want other options. This is just a minimal set. I've already got a version of PHP running with my main web server, so I put this one in a different directory in /usr/lib/.

http://www.php.net/manual/en/install.unix.apache2.php

Configure Apache to server PHP4 content.

shell> vi /usr/local/apache-2.0.59/conf/httpd.conf

# Load the PHP4 module.
LoadModule php4_module modules/libphp4.so

# Associate the three listed extensions with a PHP mime-type.
AddType application/x-httpd-php .php .phtml .php3
              
# Turn up the error reporting in Apache since we're going to be
# screwing around.  Change this back to a higher level once
# everything is working OK.
LogLevel debug

http://httpd.apache.org/docs/2.0/mod/directives.html

Test the setup so far

Screenshot showing Apache being started with PHP4 enabled.

Looks like everything is OK so far.

Install mod_fastcgi 2.4.2

shell> cd /usr/local/src/mod_fastcgi-2.4.2

Use the apxs program to compile *.c into a shared object
called 'mod_fastcgi.so'.
shell> /usr/local/apache-2.0.59/bin/apxs -o mod_fastcgi.so -c *.c     

Change to the directory where the .so ends up.
shell> cd .libs

Install the module.
shell> /usr/local/apache-2.0.59/bin/apxs -i 
-n fastcgi mod_fastcgi.so

Note : mod_fastcgi 2.4.2 will not compile if you are running Apache 2.2. I found a patch which will allow mod_fastcgi to compile with apxs for Apache 2.2.

http://httpd.apache.org/docs/2.0/programs/apxs.html

Setup work for mod_fastcgi

FastCGI needs a directory where it can create sockets for inter-process communication.

# Create the main fcgi-ipc directory, and 1 subdirectory
# This can be anywhere.  If your system automatically removes 
# things from /tmp, FastCGI will break.
shell> mkdir -p /tmp/fcgi-ipc/dynamic

# Make the directory world-accessible.
shell> chmod -R 0777 /tmp/fcgi-ipc

Configure Apache and mod_fastcgi

shell> vi /usr/local/apache-2.0.59/conf/httpd.conf

LoadModule modules/mod_fastcgi.so

# Tell FastCGI where to create its IPC sockets.
FastCgiIpcDir /tmp/fcgi_ipc/

# Tell Apache that .fcgi files should be handled by
# FastCGI.  'fastcgi-script' is a handler that mod_fastcgi
# registers in Apache.
AddHandler fastcgi-script .fcgi

http://www.fastcgi.com/mod_fastcgi/docs/mod_fastcgi.html
http://www.fastcgi.com/mod_fastcgi/docs/mod_fastcgi.html#FastCgiIpcDir

Time to test again.

Screenshot showing Apache being started with PHP4 and mod_fastcgi enabled.

Looks like everything is still OK.

3 ways to access a FastCGI program

http://www.fastcgi.com/mod_fastcgi/docs/mod_fastcgi.html

Install PHP 5.1.5

shell> cd /usr/local/src/php-5.1.5
shell> ./configure 
          --prefix=/usr/local/php5-fcgi --enable-fastcgi
          --enable-memory-limit --with-mysql
          
          # a security measure useful when the PHP binary 
          # will not be located in the webserver's document root.
          --enable-discard-path
          
          # Enable the security check for internal 
          # server redirects.  You should use this if
          #you are running the CGI version with Apache
          --enable-force-cgi-redirect

shell> make
shell> make install

Configure Apache to pass PHP requests to FastCGI

shell> vi /usr/local/apache-2.0.59/conf/httpd.conf

# Invent a new Apache handler, and tell Apache any .php5
# files should be handled by it.
AddHandler php5-fcgi .php5

# Tell Apache that any requests for php5 content should be
# directed to a script called php5.fcgi
# php5.fcgi is covered in the next slide.
Action php5-fcgi /php5.fcgi

Remember, anything called .fcgi is treated as a FastCGI program.
If you want .php files some directories to be PHP5, add this to Apache's configuration:

<Directory /usr/local/apache-2.0.59/htdocs/all5>
   AddHandler php5-fcgi .php
</Directory>

So what is php5.fcgi?

It's a shell script that set a few environment variables and runs the PHP binary. Originally from this howto. README.FastCGI in the PHP source code has information on the 2 environment variables, and a few others. They are somewhat redundant with options available in FastCGI configurations. You can decide which approach you'd rather take.

#!/bin/sh
PHP_FCGI_CHILDREN=4
export PHP_FCGI_CHILDREN
PHP_FCGI_MAX_REQUESTS=5000
export PHP_FCGI_MAX_REQUESTS
exec /usr/local/php5-fcgi/bin/php -c /etc/php5/apache2/php.ini

PHP_FCGI_CHILDREN : gives you better concurrency at the cost of more memory.

PHP_FCGI_MAX_REQUESTS : Kills a process after it has handled the given # of requests.

More on php5.fcgi setup

So does it run?

Screenshot showing system processes running as user nobody.  Apache and fastcgi processes.

Some phpinfo() screeshots

Screenshot of PHP4 phpinfo() output Screenshot of PHP5 phpinfo() output

Links

Tutorials


This slideshow created with S5. (Simple Standards-Based Slide Show System)