This post is about how to install PHP-FPM, which is a replacement for spawn-fcgi (LightTPD). Why would we replace spawn-fcgi? Because we have troubles with it: it crashes and/or hangs. As a temporary solution, we created a script that automatically restarts it, but we prefer a clean, permanent solution. This solution may be replacing spawn-fcgi by PHP-FPM.
1 - Getting the files
First of all, PHP-FPM is BUILT-IN PHP; it's a patch for the source code. So, obviously, you need the PHP source code and the right version of PHP-FPM. Our PHP version is 4.4.8 and fortunately PHP-FPM exists for PHP 4.4.8.
The PHP-FPM download page is here.
cd /root
wget http://php-fpm.anight.org/downloads/head/php-4.4.8-fpm-0.5.8.diff.gz
wget http://us2.php.net/get/php-4.4.8.tar.gz/from/this/mirror
wget http://php-fpm.anight.org/downloads/head/php-4.4.8-fpm-0.5.8.diff.gz
wget http://us2.php.net/get/php-4.4.8.tar.gz/from/this/mirror
2 - Patching PHP
As I said above, PHP-FPM is a patch for the PHP source code. So to use it...
cd /usr/local/src
tar xvfz /root/php-4.4.8.tar.gz
gzip -cd /root/php-4.4.8-fpm-0.5.8.diff.gz | patch -d php-4.4.8 -p1
tar xvfz /root/php-4.4.8.tar.gz
gzip -cd /root/php-4.4.8-fpm-0.5.8.diff.gz | patch -d php-4.4.8 -p1
PHP 4.4.8 is now patched with PHP-FPM and ready to be installed normally (almost).
3 - Installing PHP
Now that PHP is patched with PHP-FPM, you can install PHP as usual, except that you have to add the "--enable-fastcgi --enable-fpm" switch to your "./configure" command.
Mine was:
./configure --enable-fastcgi --enable-fpm --with-mcrypt --enable-mbstring --enable-mysql --with-mysql=/usr/local/mysql --with-mysql-sock=/tmp/mysql.sock --with-curl --with-sockets --with-gd --with-zlib --with-iconv --with-dom --with-jpeg-dir=/usr/lib
Then, instead of "make", you must do:
make all
And finally:
make install
4 - Configuring PHP-FPM
Once installed, PHP-FPM has created its configuration file: /usr/local/etc/php-fpm.conf. In this file, you will find plenty of possible tweaks. As for me, the only thing I changed was to uncomment these two lines and put the user/group I wanted:
Unix user of processes
www
Unix group of processes
www
www
Unix group of processes
www
If your Web server is using another port than 9000 for FastCGI calls, change the port for the one you want in php-fpm.conf.
5 - Launching PHP-FPM
Launching PHP-FPM is a piece of cake. All you have to do is:
/path/to/php-cgi --fpm
If your php.ini file isn't at the default location (normally /usr/local/lib/php.ini), you may want to include the -c parameter in the launch command:
/path/to/php-cgi --fpm -c /path/to/php.ini
Now PHP-FPM should be running and everything should work correctly. You can see "PHP-FPM" version and information in phpinfo().
6 - Start/auto-restart script
To start/auto-restart PHP-FPM (or spawn-fcgi), you can use the following script. Simply modify the parameters in the top part to fit your configuration.
Note that when I wrote this script, I didn't know about the "php-fpm" script shipped with PHP-FPM. This script allows you to do php-fpm start|stop|restart|quit|etc.
If you wish to use the following script, you will need sendEmail to receive emails. You can download it at http://caspian.dotconf.net/menu/Software/SendEmail/
#!/bin/sh
# (bof)
# Settings
########################################################
#
# Method
# 'php-fpm' or 'spawn-fcgi'
method="php-fpm"
#method="spawn-fcgi"
#
# Port
# Your FastCGI port
fcgi_port=9000
#
# spawn-fcgi method settings
#
spawn_php="/path/to/php-cgi"
spawn_cmd="/path/to/spawn-fcgi.sh"
#
# php-fpm method settings
#
fpm_php="/path/to/php-cgi --fpm"
fpm_cmd="$fpm_php"
#
# Mail settings
#
m_from="from@domain.tld"
m_dest="to1@domain.tld to2@domain.tld"
m_smtp="smtp.server.com"
m_subj="PHP was restarted on machine_x"
#
########################################################
# *** YOU SHOULD NOT CHANGE ANYTHING PAST THIS POINT ***
########################################################
# Temp file
tmp="/tmp/fix.$$"
# Command line options
debug=0
backg=0
if [ -n "$1" ]
then
if [ "$1" = "debug" ]
then
debug=1
else
backg=1
fi
fi
# Output to file?
[ $backg = 1 ] && exec 1>$tmp 2>&1 3>&1
echo ""
echo "Uptime: $(uptime)"
echo "Method: $method"
echo ""
# Init
if [ "$method" = "spawn-fcgi" ]
then
php="$spawn_php"
cmd="$spawn_cmd"
else
php="$fpm_php"
cmd="$fpm_cmd"
fi
must_kill=0
must_start=0
must_email=0
# Running?
pids=$(ps axw | grep "$php$" | grep -v "grep" | cut -d"?" -f1 | tr -d " ")
if [ "$pids" != "" ]
then
a=$(telnet localhost $fcgi_port null 2>/dev/null | grep "^Connected to localhost")
if [ "$a" = "" ]
then
echo "PHP is running but NOT accepting connections!"
must_kill=1
must_start=1
else
echo "PHP is running and accepting connections!"
fi
else
echo "PHP is stopped!"
must_start=1
fi
# Debug
if [ $debug = 1 ]
then
must_kill=1
must_start=1
must_email=0
fi
# Must kill?
if [ $must_kill = 1 ]
then
echo ""
echo "Stopping PHP..."
for pid in $pids
do
kill $pid >/dev/null 2>&1
done
# Wait for all pids to disappear
pids="!"
while [ -n "$pids" ]
do
pids=$(ps axw | grep "$php$" | grep -v "grep" | cut -d"?" -f1 | tr -d " ")
done
echo "PHP was stopped!"
must_email=1
fi
# Must start?
if [ $must_start = 1 ]
then
echo ""
echo "Starting PHP..."
$cmd
echo "PHP was started!"
must_email=1
fi
echo ""
echo "Done!"
echo ""
# Must email?
if [ $must_email = 1 -a $backg = 1 ]
then
/path/to/sendEmail -u "$m_subj" /
-f "$m_from" /
-t "$m_dest" /
-s "$m_smtp" /
-o message-file=$tmp >/dev/null 2>&1
fi
# Clean up
rm -rf $tmp
# (eof)
# (bof)
# Settings
########################################################
#
# Method
# 'php-fpm' or 'spawn-fcgi'
method="php-fpm"
#method="spawn-fcgi"
#
# Port
# Your FastCGI port
fcgi_port=9000
#
# spawn-fcgi method settings
#
spawn_php="/path/to/php-cgi"
spawn_cmd="/path/to/spawn-fcgi.sh"
#
# php-fpm method settings
#
fpm_php="/path/to/php-cgi --fpm"
fpm_cmd="$fpm_php"
#
# Mail settings
#
m_from="from@domain.tld"
m_dest="to1@domain.tld to2@domain.tld"
m_smtp="smtp.server.com"
m_subj="PHP was restarted on machine_x"
#
########################################################
# *** YOU SHOULD NOT CHANGE ANYTHING PAST THIS POINT ***
########################################################
# Temp file
tmp="/tmp/fix.$$"
# Command line options
debug=0
backg=0
if [ -n "$1" ]
then
if [ "$1" = "debug" ]
then
debug=1
else
backg=1
fi
fi
# Output to file?
[ $backg = 1 ] && exec 1>$tmp 2>&1 3>&1
echo ""
echo "Uptime: $(uptime)"
echo "Method: $method"
echo ""
# Init
if [ "$method" = "spawn-fcgi" ]
then
php="$spawn_php"
cmd="$spawn_cmd"
else
php="$fpm_php"
cmd="$fpm_cmd"
fi
must_kill=0
must_start=0
must_email=0
# Running?
pids=$(ps axw | grep "$php$" | grep -v "grep" | cut -d"?" -f1 | tr -d " ")
if [ "$pids" != "" ]
then
a=$(telnet localhost $fcgi_port null 2>/dev/null | grep "^Connected to localhost")
if [ "$a" = "" ]
then
echo "PHP is running but NOT accepting connections!"
must_kill=1
must_start=1
else
echo "PHP is running and accepting connections!"
fi
else
echo "PHP is stopped!"
must_start=1
fi
# Debug
if [ $debug = 1 ]
then
must_kill=1
must_start=1
must_email=0
fi
# Must kill?
if [ $must_kill = 1 ]
then
echo ""
echo "Stopping PHP..."
for pid in $pids
do
kill $pid >/dev/null 2>&1
done
# Wait for all pids to disappear
pids="!"
while [ -n "$pids" ]
do
pids=$(ps axw | grep "$php$" | grep -v "grep" | cut -d"?" -f1 | tr -d " ")
done
echo "PHP was stopped!"
must_email=1
fi
# Must start?
if [ $must_start = 1 ]
then
echo ""
echo "Starting PHP..."
$cmd
echo "PHP was started!"
must_email=1
fi
echo ""
echo "Done!"
echo ""
# Must email?
if [ $must_email = 1 -a $backg = 1 ]
then
/path/to/sendEmail -u "$m_subj" /
-f "$m_from" /
-t "$m_dest" /
-s "$m_smtp" /
-o message-file=$tmp >/dev/null 2>&1
fi
# Clean up
rm -rf $tmp
# (eof)
Conclusion
Installing PHP-FPM is very easy and, as it is built-in PHP, should be faster than spawn-fcgi. It is also more convenient to configure and launch.
Resources
PHP-FPM home page
http://php-fpm.anight.org/
Interesting article on optimization of Nginx/PHP-FPM
http://groups.google.com/group/highl...c4392ec5caf6d1