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

Want to help support this blog? Try out Oh Dear, the best all-in-one monitoring tool for your entire website, co-founded by me (the guy that wrote this blogpost). Start with a 10-day trial, no strings attached.

We offer uptime monitoring, SSL checks, broken links checking, performance & cronjob monitoring, branded status pages & so much more. Try us out today!

Profile image of Mattias Geniar

Mattias Geniar, April 21, 2011

Follow me on Twitter as @mattiasgeniar

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 "http://be.php.net/get/php-5.3.6.tar.gz/from/this/mirror"
# 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/init.d.php-fpm.in /etc/init.d/php-fpm
# chmod 755 /etc/init.d/php-fpm
# cp sapi/fpm/php-fpm.conf.in /etc/php-fpm.conf

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

php_fpm_BIN=/usr/local/sbin/php-fpm
php_fpm_CONF=/etc/php-fpm.conf
php_fpm_PID=/var/run/php-fpm/php-fpm.pid

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.

[global]
pid = /var/run/php-fpm/php-fpm.pid
listen = 127.0.0.1:9000
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
done
# lsof -i tcp:9000
COMMAND  PID    USER   FD   TYPE    DEVICE SIZE NODE NAME
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 "http://nginx.org/download/nginx-1.0.0.tar.gz"
# 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 {
    server 127.0.0.1:9000;
}

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!



Want to subscribe to the cron.weekly newsletter?

I write a weekly-ish newsletter on Linux, open source & webdevelopment called cron.weekly.

It features the latest news, guides & tutorials and new open source projects. You can sign up via email below.

No spam. Just some good, practical Linux & open source content.