← All Articles

Serving PHP with FPM (FastCGI) using Nginx on CentOS

PHP-FPM is an alternative FastCGI implementation which I prefer for keeping resources manageable in a moderate - high traffic site. You can read about some of the advantages and disadvantages elsewhere, this article is a how-to guide for installing and configuration using Nginx on CentOS.

Step 1 - Install PHP with related libraries

$ yum install php php-mysql php-common php-gd php-fpm php-mbstring php-mcrypt php-devel php-xml


Step 2 - Start PHP-FPM

$ php-fpm on

And also make sure it starts when your server boots up.

$ chkconfig php-fpm on


Step 3 - Install the EPEL repo

Installing alternative repos allows you to install packages not included in the default yum package manager for CentOS.

Two repos which I recommend installing are the EPEL (Extra Packages for Enterprise Linux) and Remi repos. These will ensure you have a more up to date Nginx installation.

$ wget
$ wget
$ sudo rpm -Uvh remi-release-6*.rpm epel-release-6*.rpm

Verify that the EPEL repo is installed, by checking that you have the following files:


Then you need to enable the Remi repo, by making sure that you have enabled=1 for when editing:

$ sudo nano /etc/yum.repos.d/remi.repo


Step 4 - Install Nginx

Now that you have the extra repos installed, install Nginx by running:

$ yum install nginx


Step 5 - Configure Nginx

You will also need a Nginx config file for your site. Usually, this would be a new file you create in /etc/nginx/conf.d/ and looks something like this:

server {
    listen 80 default;
    gzip_static on;

    root /var/www/my-site;

    location ^~ /blog {
        root /var/www/my-site/blog;
        index index.php index.html
        try_files $uri $uri/ index.php?q=$uri&$args;

        rewrite ^/blog(.*)$ /blog/index.php?q=$1;

        location ~ \.php$ {
            fastcgi_index index.php;
            fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
            include fastcgi_params;

        # This block will catch static file requests, such as images, css, js
        # The ?: prefix is a 'non-capturing' mark, meaning we do not require
        # the pattern to be captured into $1 which should help improve performance
        location ~* \.(?:ico|css|js|gif|jpe?g|png|eot|svg|ttf|woff|txt)$ {
                # Some basic cache-control for static files to be sent to the browser
                expires max;
                add_header Pragma public;
                add_header Cache-Control "public, must-revalidate, proxy-revalidate";



This config file basically serves files from the /var/www/my-site directory for any visitors to, *except* if the visitor comes to anything from If this happens, then we ask Nginx to send any PHP files to FastCGI. An exception is made to serve static files (like image, CSS, or javascript files) directly from Nginx.

I usually also like to add an init file so that you can easily start or stop Nginx using commands like sudo /etc/init.d/nginx start and sudo /etc/init.d/nginx stop respectively. You can do this by adding the following file at /etc/init.d/nginx:

# nginx - this script starts and stops the nginx daemin. It should be kept in /etc/init.d/nginx
# chkconfig:   - 85 15 
# description:  Nginx is an HTTP(S) server, HTTP(S) reverse \
#               proxy and IMAP/POP3 proxy server
# processname: nginx
# config:      /usr/local/nginx/conf/nginx.conf
# pidfile:     /usr/local/nginx/logs/

# Source function library.
. /etc/rc.d/init.d/functions

# Source networking configuration.
. /etc/sysconfig/network

# Check that networking is up.
[ "$NETWORKING" = "no" ] && exit 0

prog=$(basename $nginx)



start() {
    [ -x $nginx ] || exit 5
    [ -f $NGINX_CONF_FILE ] || exit 6
    echo -n $"Starting $prog: "
    daemon $nginx -c $NGINX_CONF_FILE
    [ $retval -eq 0 ] && touch $lockfile
    return $retval

stop() {
    echo -n $"Stopping $prog: "
    killproc $prog -QUIT
    [ $retval -eq 0 ] && rm -f $lockfile
    return $retval

restart() {
    configtest || return $?

reload() {
    configtest || return $?
    echo -n $"Reloading $prog: "
    killproc $nginx -HUP

force_reload() {

configtest() {
  $nginx -t -c $NGINX_CONF_FILE

rh_status() {
    status $prog

rh_status_q() {
    rh_status >/dev/null 2>&1

case "$1" in
        rh_status_q && exit 0
        rh_status_q || exit 0
        rh_status_q || exit 7
        rh_status_q || exit 0
        echo $"Usage: $0 {start|stop|status|restart|condrestart|try-restart|reload|force-reload|configtest}"
        exit 2

Lastly, make sure you setup the correct permissions for the init file, and set Nginx to start when your server starts.

$ sudo chmod a+x /etc/init.d/nginx
$ sudo /etc/init.d/nginx start
$ chkconfig nginx on

And that's it, your PHP files should now be served via PHP-FPM.

Made with JoyBird