ipHouse Logo

A long, long time ago (Internet years), our webmaster (and Mike) changed the ipHouse web-cluster to run PHP via FastCGI. They did this with the thought that FCGId would offer greater performance and stability while offering the same security as running PHP via the CGI interface.

Around the same time I also tried implementing FCGId in Ubuntu on one of my virtual servers. It worked well, but I thought it was a bit verbose. Recently, I took on the project to set up FCGId for a managed customer. I decided to ask our webmaster how he implemented FGCI via the FCGIwrapper primitive and still get suEXEC to work.

He showed me his configuration, which looked something like this:

php-fcgi.conf

# Load the FastCGI module
LoadModule fcgid_module libexec/mod_fcgid.so
# Assign PHP scripts to the FastCGI module
AddHandler fcgid-script .php
# Execute PHP scripts via the fcgid_php wrapper script
FcgidWrapper /webroot/cgi-bin/fcgid_php .php
# Enable additional script path processing
# Make sure that cgi.fix_pathinfo is set to 1 in php.ini
FcgidFixPathInfo 1
# Terminate processes after handling some number of requests
FcgidMaxRequestsPerProcess 10000

and the wrapper script:

#!/bin/sh
export PHP_FCGI_MAX_REQUESTS=’10001′
ulimit -c 0
ulimit -t 3600
exec /usr/local/bin/php-cgi

But wait, I responded, suEXEC won’t run a script owned by root. How did you get that to work?

He responded “Oh, I modified the source code, here you go…”

Ah, no… For I am but a mortal System Administrator, and do not wish to meddle in such affairs.

So, I went back to what I was originally doing. It was still verbose. However, there is a happy medium.

What *I* did on my web cluster and personal server was add a custom wrapper, handler, and ScriptAlias for FGCI for each user. You do need a custom wrapper and ScriptAlias, but you can have a global handler tied to a relative path via mod actions.

So my php-fcgi.conf looks something like this:

php-fcgi.conf

# Assign PHP scripts to Actions module
AddHandler fcgid-script .php
Action fcgid-script /fcgi-bin/php-fcgi-wrapper
#Notice the *Relative* path. It’s not an absolute path
# Execute PHP scripts via the fcgid_php wrapper script
# Enable additional script path processing
# Make sure that cgi.fix_pathinfo is set to 1 in php.ini
FcgidFixPathInfo 1
# Terminate processes after handling some number of requests
FcgidMaxRequestsPerProcess 10000

The wrapper is basically the same as above. Now you just have to add to each virtual host:

ScriptAlias /fcgi-bin/ /webroot/www/fcgid/username/

There, now I don’t need to rebuild suEXEC every time I update Apache.

And make sure that there is a copy of wrapper owned by the suEXEC-named user in each /username/ directory.