Apache mod_fastcgi and PHP with PHP-FPM
Recently I did a server migration from an older server to a newer server and in an attempt to help stability I wanted to see if there was a better way to do PHP FastCGI. In my research I came across running PHP using the FastCGI server that spins up a PHP on a TCP/IP port and allows the web server to connect to it. However this doesn't help with spawning or keeping track of instances or error recovery.
This is where PHP-FPM comes in handy. It does all of the hard work for us, it spawns the processes and has a bunch of really awesome features that help run PHP as various different users as required with different PHP ini files and memory limits. PHP-FPM's defaults, at least from a ports install, are extremely sane and I don't really suggest changing them. After setting up PHP FPM I had to set up Apache.
mod_fcgid
doesn't allow for remote connections, and as such I was unable to use
it for what I needed it for. mod_fastcgi
provides the
FastCGIExternalServer configuration key, which is exactly what I needed.
"The FastCgiExternalServer directive defines filename as an external FastCGI application. If filename does not begin with a slash (
/
) then it is assumed to be relative to theServerRoot
. The filename does not have to exist in the local filesystem. URIs that Apache resolves to this filename will be handled by this external FastCGI application."
What this documentation does not state is that the path up to the last part of
it has to exist in the local file system. So in my first couple of attempts I
pointed it at /usr/local/www/fastcgi/php5.fcgi
without having an actual fastcgi
directory located in /usr/local/www/
. There are a lot of examples that require
creating a new FastCGIExternalServer
for each and every VirtualHost
this is
unacceptable to me, the reason they require it is because they set the
FastCGIExternalServer
path to the folder where they are going to be serving
files from.
In the end I found that after creating the /usr/local/www/fastcgi
directory
(and reading the mod_fastcgi
source code) that all it does is make Apache
believe a file exists in a certain directory, much like Alias
, except Alias
allows full paths to be aliased, not so here.
The AddType
and Action
add custom types and what the action should be when
such a type is encountered. In this case the action is to redirect the request
to /php5.fcgi
which will handle the rest of the request. This does not require
another FastCGI section per VirtualHost
as each PHP request will just get
shuttled to the php handler.
Do take note that I have specifically disallowed Apache to serve anything from
the /usr/local/www/fastcgi/
folder, except for a single file php5.fcgi
which is our FastCGIExternalServer
file.
<IfModule mod_fastcgi.c> Alias /php5.fcgi /usr/local/www/fastcgi/php5.fcgi FastCGIExternalServer /usr/local/www/fastcgi/php5.fcgi -flush -host 127.0.0.1:9000 AddType application/x-httpd-fastphp5 .php Action application/x-httpd-fastphp5 /php5.fcgi <Directory "/usr/local/www/fastcgi/"> Order deny,allow Deny from all <Files "php5.fcgi"> Order allow,deny Allow from all </Files> </Directory> </IfModule>
Note that even-though in my last post concerning mod_fastcgi
I as moving
away from it, I am now doing the opposite, instead of moving from
mod_fastcgi
to mod_fcgid
I'm back to mod_fastcgi
, only because
mod_fcgid
doesn't offer the same functionality.
So far this has provided far more stability, along with PHP-FPM doing all of
the process management I can now use a single PHP instance that is running on a
single port for the various web servers I am testing. At the moment I have both
Lighttpd and Apache using the same PHP-FPM instance. It is faster, less
memory is wasted and PHP-FPM is much better at process management than
mod_fastcgi
or mod_fcgid
.