Guide: running NginX 1.0 with PHP-FPM 5.3 on CentOS 5.x

This is a very easy/simple NginX + PHP-FPM guide.

PHP-FPM configuration

First, download the latest version of PHP (5.3.6 as of this writing) and compile it with the --enable-fpm parameter to allow for the php-fpm binary to be built.

# cd /usr/local/src/
# wget ""
# tar xzf php-5.3.6.tar.gz
# rm php-5.3.6.tar.gz
# cd php-5.3.6/
# ./configure --enable-fpm --with-mhash --with-mcrypt --with-mysql --with-mysqli --with-pdo-mysql --with-libdir=lib64
# make
# make install

A few notes here:

  • --enable-fpm: needed to enable the FastCGI Process Manager
  • --with-libdir: since I'm running on x64, I need to tell the configure-command to look for libraries in /usr/lib64 instead of the default /usr/lib.

The rest is just the most basic PHP I could imagine, to run a simple website. Yours might need more modules enabled.

Now, copy some config files you'll need.

# cp sapi/fpm/ /etc/init.d/php-fpm
# chmod 755 /etc/init.d/php-fpm
# cp sapi/fpm/ /etc/php-fpm.conf

Edit your /etc/init.d/php-fpm and adjust the following values for your system.


Make sure the path to the PID file is in a directory where the PHP-FPM user can write to, otherwise you'll see your php-fpm children start but the init.d script still return failures.

Now edit your /etc/php-fpm.conf the enable at least the following.

pid = /var/run/php-fpm/
listen =
user = php-fpm
group = php-fpm
pm = dynamic
pm.max_children = 50
pm.start_servers = 4
pm.min_spare_servers = 3
pm.max_spare_servers = 35

Note that the path to the PID-file is the same as defined in the init.d script. Make sure you run the php-fpm as an existing user. You'll probably have to add the php-fpm user first.

# useradd php-fpm
# mkdir -p /var/run/php-fpm
# chown php-fpm.php-fpm /var/run/php-fpm

You should be able to start php-fpm now, after which it'll be running on port 9000.

# /etc/init.d/php-fpm start
# lsof -i tcp:9000
php-fpm 5140    root    6u  IPv4 123964005       TCP localhost.localdomain:cslistener (LISTEN)
php-fpm 5142 php-fpm    0u  IPv4 123964005       TCP localhost.localdomain:cslistener (LISTEN)
php-fpm 5143 php-fpm    0u  IPv4 123964005       TCP localhost.localdomain:cslistener (LISTEN)
php-fpm 5144 php-fpm    0u  IPv4 123964005       TCP localhost.localdomain:cslistener (LISTEN)
php-fpm 5145 php-fpm    0u  IPv4 123964005       TCP localhost.localdomain:cslistener (LISTEN)

That's it for the (very basic) PHP-FPM installation. Now, on to Nginx.

NginX configuration

Download and compile nginx for your system.

# cd /usr/local/src/
# wget ""
# tar xzf nginx-1.0.0.tar.gz ; rm nginx-1.0.0.tar.gz
# cd nginx-1.0.0/
# ./configure --without-mail_pop3_module --without-mail_imap_module --without-mail_smtp_module
# make && make install

The above will compile NginX without the mail-support for IMAP, POP3 and SMTP since I only want to run it as a webserver, not load balance mail protocols.

Now, have a look at your configuration file for NginX.

vim /usr/local/nginx/conf/nginx.conf

And add something like the following config to it. It has plenty of comments to explain the configuration.

upstream backend_php {

The above will create a new "pool" of PHP FastCGI servers. So you can have multiple of them, and have them be "load balanced" (aka: round robin style by default) amongst them.

server {
    listen 80 default;
    server_name tryout-hostname;

    # First look for the index.php, then index.html
    index index.php index.html;

    # Where do we log stuff?
    access_log /var/log/nginx/access.log combined; # buffer=8k;
    error_log /var/log/nginx/error.log info;

    # The documentroot of the site.
    root /var/www/html/;

    # Want to add a custom header?
    add_header      X-Random-Info   "FooBar?";

    # Extend this list with other static files you may have
    location ~* ^.+.(jpg|jpeg)$ {
        # Static content? Set some expire-headers.
        expires 30d;

        # If your site is getting a lot of static request, you may want to
        # keep them from getting in your access logs. Usually worthless
        # anyhow.
        access_log off;

    # Is the file ending in the .php extension?
    location ~\.php$ {
        # Include the FastCGI parameters as defined by Nginx
        include fastcgi_params;

        # Configure the fastCGI
        fastcgi_split_path_info ^(.+\.php)(.*)$;
        fastcgi_index  index.php;
        fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;

        if (-f $request_filename) {
            # Only throw it at PHP-FPM if the file exists (prevents some PHP exploits)
            fastcgi_pass   backend_php; # The upstream determined above

After that, you should be able to start your NginX webserver.

# /usr/local/nginx/sbin/nginx

You can restart it or stop it like so.

# /usr/local/nginx/sbin/nginx -s reload
# /usr/local/nginx/sbin/nginx -s stop

Hope this gets you started somewhat, feel free to add additional tips or configuration errors I made in the comments!

Write a Comment

Do you care about the markup if your comment? You can use the following HTML tags:

<code>command</code>: command highlighting
<pre>text</pre>: pre-formatted code, can be multi-line (black background, white letters)

example <pre> tag
<blockquote>text</blockquote> quoted text
quoted example

None of this is needed of course, I appreciated your comment nonetheless!



  1. Not yet, that’s on my todo-list after I get back from holidays. Comparing to Apache + mod_php, Apache + FastCGi, Lighttpd + FastCGI, Squid, … but this feels a lot faster. Greatest drawback: no default mod_rewrite in .htaccess rules, so you’ll have to convert any mod_rewrites to this particular setup.

    • Because:
      – you have most control over the options you want to enable or disable (repo’s usually contain RPMs that have -all- options enabled)
      – you can choose a specific version (stable or beta) if you need it, much faster to get bugfixes that apply to you