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

Mattias Geniar, Thursday, April 21, 2011 - last modified: Tuesday, February 21, 2012

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!


Hi! My name is Mattias Geniar. I'm a Support Manager at Nucleus Hosting in Belgium, a general web geek, public speaker and podcaster. If you're interested in keeping up with me, have a look at my podcast and weekly newsletter below. For more updates, follow me on Twitter as @mattiasgeniar.

SysCast podcast

In the SysCast podcast I talk about Linux & open source projects, interview sysadmins or developers and discuss web-related technologies. A show by and for geeks!

cron.weekly newsletter

A weekly newsletter - delivered every Sunday - for Linux sysadmins and open source users. It helps keeps you informed about open source projects, Linux guides & tutorials and the latest news.

Share this post

Did you like this post? Will you help me share it on social media? Thanks!

Comments

Jonas Monday, May 2, 2011 at 21:27

Great info, thx. Any speed comparison with a more classic setup available?

Reply


Matti Monday, May 2, 2011 at 22:44

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.

Reply


Taz Thursday, December 22, 2011 at 13:52

wtf? why not use westatic repo? why should i compile from source?

Reply


    Matti Thursday, December 22, 2011 at 13:59

    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

    Reply


gadelkareem Thursday, March 15, 2012 at 23:59

Another way to do it … Install PHP 5.3.10 with PHP-FPM on CentOS 6.2

Reply


milad Wednesday, January 16, 2013 at 21:25

after read all article about php-fpm and nginx,only this article work fine.

Reply


Devendra Tuesday, July 7, 2015 at 14:57

After trying to start php-fpm if you get “uknown entry” error.

Don’t copy the entries from here. Just change values of the entries already existing in php-fpm.conf

Reply


Leave a Reply

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

Inbound links