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 the ServerRoot
. 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
.