Have you moved your site from Apache to Nginx and now your FastCGI (php-cgi/spawn-fcgi) processes die/hang/crash periodically and your users see “HTTP 502 Bad gateway” or “HTTP 504 Gateway timeout” instead of a website?

I have faced this problem and found a relatively simple and robust solution. Here’s how I did it on Ubuntu 9.10 (Karmic Koala) and 10.04 (Lucid Lynx) server edition.

Solution was to replace default FastCGI implementation with PHP-FPM (FastCGI Process Manager). PHP-FPM is not supported in PHP out of the box – so if you use PHP 5.2.*, you’ll need to apply a patch and recompile PHP, and if you’re using PHP 5.3.* (at least in 5.3.2 PHP-FPM is not yet in the core) – you’ll need to check out PHP-FPM from PHP SVN.

Let’s start with uninstalling default Ubuntu php packages:

sudo apt-get remove php5*

Now we need to install dependencies. Note, that Ubuntu comes with a new autoconf tool version, which is not compatible with PHP, that’s why for successful compilation you need to temporarily install autoconf2.13 package.

sudo apt-get install libcurl4-openssl-dev libmcrypt-dev libxml2-dev libpng-dev 
autoconf2.13 libevent-dev libltdl-dev

Download latest stable PHP 5.2.13, Suhosin patch, PHP-FPM patch

cd ~/tmp
wget http://pl2.php.net/get/php-5.2.13.tar.gz/from/pl.php.net/mirror
wget http://download.suhosin.org/suhosin-patch-5.2.13-0.9.7.patch.gz
wget http://php-fpm.org/downloads/php-5.2.13-fpm-0.5.13.diff.gz
tar xvzf php-5.2.13.tar.gz
gunzip suhosin-patch-5.2.13-0.9.7.patch.gz
gunzip php-5.2.13-fpm-0.5.13.diff.gz
cd php-5.2.13
patch -p 1 -i ../php-5.2.13-fpm-0.5.13.diff
patch -p 1 -i ../suhosin-patch-5.2.13-0.9.7.patch
./buildconf --force
./configure --enable-fastcgi --enable-fpm --with-mcrypt --with-zlib --enable-mbstring --with-openssl 
--with-mysql --with-mysql-sock --with-gd --without-sqlite --disable-pdo
make
make test
sudo make install

Alternatively you can download latest stable PHP 5.3.2, Suhosin patch, apply PHP-FPM patch. Note, that not all PHP based projects and plugins work correctly with new PHP 5.3 – it is not backwards compatible with PHP 5.2. I had troubles at least with some Joomla plugins and ZenCart.

cd ~/tmp
http://fi.php.net/get/php-5.3.2.tar.gz/from/this/mirror
wget http://download.suhosin.org/suhosin-patch-5.3.2-0.9.9.1.patch.gz
tar xvzf php-5.3.2.tar.gz
gunzip suhosin-patch-5.3.2-0.9.9.1.patch.gz
cd php-5.3.2
patch -p 1 -i ../suhosin-patch-5.3.2-0.9.9.1.patch
svn co http://svn.php.net/repository/php/php-src/trunk/sapi/fpm sapi/fpm
./buildconf --force
./configure --enable-fastcgi --enable-fpm --with-mcrypt --with-zlib --enable-mbstring --with-openssl 
--with-mysql --with-mysql-sock --with-gd --without-sqlite --disable-pdo --disable-reflection
make
make test
sudo make install

Uninstall autoconf2.13 after compilation.

sudo apt-get remove autoconf2.13

Change user and group of php-fpm processes to user and group of your choice (e.g. www-data and www-data) – lines 63 and 66

sudo vim /usr/local/etc/php-fpm.conf

Edit PHP settings

sudo vim /etc/php5/cgi/php.ini (in Ubuntu 9.xx)
sudo vim /etc/php5/apache2/php.ini (in Ubuntu 10.04)

Set:

max_execution_time = 30
memory_limit = 128M
error_reporting = E_COMPILE_ERROR|E_RECOVERABLE_ERROR|E_ERROR|E_CORE_ERROR
display_errors = Off
log_errors = On
error_log = /var/log/php.log
register_globals = Off

Now if you haven’t done so yet, install Nginx. Ubuntu 10.04 comes with the latest stable Nginx 0.7.65, so just do:

sudo apt-get install nginx

Now you can congifure your sites, e.g. for WordPress Nginx configuration can look like this:

server {
        listen   80;
        server_name  blog.mysite.com;

        access_log  /home/user/logs/blog.mysite.com/access.log;

        location / {
          root   /home/user/blog.mysite.com;
          index  index.php index.html index.htm;

          # this serves static files that exist without running other rewrite tests
          if (-f $request_filename) {
              expires 30d;
              break;
          }

          # this sends all non-existing file or directory requests to index.php
          if (!-e $request_filename) {
              rewrite ^(.+)$ /index.php?q=$1 last;
          }

        }

        # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
        #
        location ~ \.php$ {
          include /etc/nginx/fastcgi_params;
          fastcgi_pass  127.0.0.1:9000;
          fastcgi_index index.php;
          fastcgi_param  SCRIPT_FILENAME  /home/user/blog.mysite.com/$fastcgi_script_name;
        }

        # deny access to .htaccess files, if Apache's document root
        # concurs with nginx's one
        #
        location ~ /\.ht {
          deny  all;
        }
}

9 thoughts on “Moving Joomla, WordPress and other PHP/FastCGI apps to Nginx

  1. Is it possible to have multiple(virtual hosts) domains(joomla) on a vps with nginx(php5.2.13)+msql5?

    Joomla is a must. 🙂

    thanks

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.