How to Configure Nginx to Execute PHP Using PHP-FPM

Nginx is pronounced as “Engine-X”, which is a web server and reverse proxy server. Nginx is well known for its speed and ability to handle large number of requests simultaneously with optimal use of resources.

PHP-FPM stands for “PHP-FastCGI process manager”. CGI refers to the common gateway interface which is scripted to work as a interface between the web server and dynamic content serving programs. It listens on a port much like the web server itself does, and passes the request between the PHP and web server.

This tutorial provides instructions on how to install and configure Nginx with PHP-FPM, which will help you to execute PHP programs in Nginx.

As we discussed earlier in Apache vs Nginx, when compared to Nginx, Apache is relatively slow while handling heavy load and processing large number of requests.

1. Install Nginx

You can either install Nginx from source, or install it using the package management tool that comes with your distro.

For example, on Ubuntu you can install nginx using apt-get as shown below.

$ sudo apt-get install nginx

Start the nginx server as shown below:

$ sudo service nginx start

Go to http://{your-ip-address} and make sure you see the Nginx’s welcome page.

2. Install PHP5-FPM

Next, install php5-fpm using the package management tool that comes with your distro.

For example, on Ubuntu you can install php5-fpm using apt-get as shown below.

$ sudo apt-get install php5-fpm

3. Add PHP Configuration to Nginx

Next, modify the /etc/nginx/sites-available/default file, and add the following lines.

$ sudo vi /etc/nginx/sites-available/default
server {
  listen   80;
  root /usr/share/nginx/www;
  index index.php index.html index.htm;
  server_name example.com;
  location / {
    try_files $uri $uri/ /index.html;
  }
  error_page 404 /404.html;
  error_page 500 502 503 504 /50x.html;
  location = /50x.html {
    root /usr/share/nginx/www;
  }
  # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
  location ~ \.php$ {
    try_files $uri =404;
    fastcgi_pass unix:/var/run/php5-fpm.sock;
    fastcgi_index index.php;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    include fastcgi_params;
  }
}

4. Set listen Parameter in php5-fpm www.conf

Next, we need to make the following changes in the php-frpm configuration.

By default, you’ll see the following listen entry in the www.conf file

$ sudo vi  /etc/php5/fpm/pool.d/www.conf
listen =  127.0.0.1:9000

In the www.conf file, leave everything as it is, and replace the above listen line with the one shown below.

$ sudo vi  /etc/php5/fpm/pool.d/www.conf
listen = /var/run/php5-fpm.sock

5. Restart the Nginx and PHP5-FPM and Test it

Restart php5-fpm and nginx as shown below

$ sudo service nginx restart

$ sudo service php5-fpm restart

Finally, create the following index.php file in the nginx document root, and test it.

$ sudo vi /usr/share/nginx/www
<?php
  phpinfo( );
?>

Finally, open your browser and go to http://localhost/index.php (or use your ip-address), which will execute the index.php file and display the php information.

Nginx + PHP FPM + PhalconPHP Installation Notes

Nginx is a free, open-source, high-performance HTTP server and reverse proxy, as well as an IMAP/POP3 proxy server. Unlike traditional servers, Nginx doesn’t rely on threads to handle requests. Instead it uses a much more scalable event-driven (asynchronous) architecture. This architecture uses small, but more importantly, predictable amounts of memory under load.

The PHP-FPM (FastCGI Process Manager) is usually used to allow Nginx to process PHP files. Nowadays, PHP-FPM is bundled with any Unix PHP distribution. Phalcon + Nginx + PHP-FPM provides a powerful set of tools that offer maximum performance for your PHP applications.

Configuring Nginx for Phalcon

The following are potential configurations you can use to setup nginx with Phalcon:

Basic configuration

Using $_GET[‘_url’] as source of URIs:

server {

    listen   80;
    server_name localhost.dev;

    index index.php index.html index.htm;
    set $root_path '/var/www/phalcon/public';
    root $root_path;

    try_files $uri $uri/ @rewrite;

    location @rewrite {
        rewrite ^/(.*)$ /index.php?_url=/$1;
    }

    location ~ \.php {
        fastcgi_pass unix:/run/php-fpm/php-fpm.sock;
        fastcgi_index /index.php;

        include /etc/nginx/fastcgi_params;

        fastcgi_split_path_info       ^(.+\.php)(/.+)$;
        fastcgi_param PATH_INFO       $fastcgi_path_info;
        fastcgi_param PATH_TRANSLATED $document_root$fastcgi_path_info;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    }

    location ~* ^/(css|img|js|flv|swf|download)/(.+)$ {
        root $root_path;
    }

    location ~ /\.ht {
        deny all;
    }
}

Using $_SERVER[‘REQUEST_URI’] as source of URIs:

server {

    listen   80;
    server_name localhost.dev;

    index index.php index.html index.htm;
    set $root_path '/var/www/phalcon/public';
    root $root_path;

    location / {
        try_files $uri $uri/ /index.php;
    }

    location ~ \.php$ {
            try_files $uri =404;
            fastcgi_split_path_info ^(.+\.php)(/.+)$;
            fastcgi_pass 127.0.0.1:9000;
            fastcgi_index index.php;
            fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
            include fastcgi_params;
    }

    location ~* ^/(css|img|js|flv|swf|download)/(.+)$ {
        root $root_path;
    }

    location ~ /\.ht {
        deny all;
    }
}

Dedicated Instance

server {
    listen       80;
    server_name  localhost;

    charset      utf-8;

    #access_log  /var/log/nginx/host.access.log  main;

    set $root_path '/srv/www/htdocs/phalcon-website/public';

    location / {
        root   $root_path;
        index  index.php index.html index.htm;

        # if file exists return it right away
        if (-f $request_filename) {
            break;
        }

        # otherwise rewrite it
        if (!-e $request_filename) {
            rewrite ^(.+)$ /index.php?_url=/$1 last;
            break;
        }
    }

    location ~ \.php {
        # try_files    $uri =404;

        fastcgi_index  /index.php;
        fastcgi_pass   127.0.0.1:9000;

        include fastcgi_params;
        fastcgi_split_path_info       ^(.+\.php)(/.+)$;
        fastcgi_param PATH_INFO       $fastcgi_path_info;
        fastcgi_param PATH_TRANSLATED $document_root$fastcgi_path_info;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    }

    location ~* ^/(css|img|js|flv|swf|download)/(.+)$ {
        root $root_path;
    }
}

Configuration by Host

And this second configuration allow you to have different configurations by host:

server {
    listen      80;
    server_name localhost;
    set         $root_path '/var/www/$host/public';
    root        $root_path;

    access_log  /var/log/nginx/$host-access.log;
    error_log   /var/log/nginx/$host-error.log error;

    index index.php index.html index.htm;

    try_files $uri $uri/ @rewrite;

    location @rewrite {
        rewrite ^/(.*)$ /index.php?_url=/$1;
    }

    location ~ \.php {
        # try_files    $uri =404;

        fastcgi_index  /index.php;
        fastcgi_pass   127.0.0.1:9000;

        include fastcgi_params;
        fastcgi_split_path_info       ^(.+\.php)(/.+)$;
        fastcgi_param PATH_INFO       $fastcgi_path_info;
        fastcgi_param PATH_TRANSLATED $document_root$fastcgi_path_info;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    }

    location ~* ^/(css|img|js|flv|swf|download)/(.+)$ {
        root $root_path;
    }

    location ~ /\.ht {
        deny all;
    }
}

How To Install (LEMP) nginx, MySQL, PHP stack on Arch Linux

About Lemp


LEMP stack is a group of open source software to get web servers up and running. The acronym stands for Linux, nginx (pronounced Engine x), MySQL, and PHP. Since the server is already running Arch Linux, the linux part is taken care of. Here is how to install the rest.

Setup


The steps in this tutorial require the user to have root privileges. You can see how to set that up in the Initial Server Setup Tutorial in steps 3 and 4.

Step One—Pacman


Because pacman, the arch package manager, has a rolling package release, we should update Arch and its repositories before proceeding with any other steps:

sudo pacman -Syu

Step Two—Install MySQL


Once everything is fresh and up to date, we can start to install the server software, beginning with MySQL.

sudo pacman -S mysql

Once MySQL installs, start both mysql and the secure installation process. You will also be able to set the MySQL root password during the installation.

sudo systemctl start mysqld && mysql_secure_installation

When initially prompted for the MySQL root password, you can go ahead and press enter, as it has not yet been set. Your installation should look like this:

Enter current password for root (enter for none): 
OK, successfully used password, moving on...

Setting the root password ensures that nobody can log into the MySQL
root user without the proper authorization.

Set root password? [Y/n] y
New password: 
Re-enter new password: 
Password updated successfully!
Reloading privilege tables..
 ... Success!

By default, a MySQL installation has an anonymous user, allowing anyone
to log into MySQL without having to have a user account created for
them.  This is intended only for testing, and to make the installation
go a bit smoother.  You should remove them before moving into a
production environment.

Remove anonymous users? [Y/n] y
 ... Success!

Normally, root should only be allowed to connect from 'localhost'.  This
ensures that someone cannot guess at the root password from the network.

Disallow root login remotely? [Y/n] y
 ... Success!

By default, MySQL comes with a database named 'test' that anyone can
access.  This is also intended only for testing, and should be removed
before moving into a production environment.

Remove test database and access to it? [Y/n] y
 - Dropping test database...
 ... Success!
 - Removing privileges on test database...
 ... Success!

Reloading the privilege tables will ensure that all changes made so far
will take effect immediately.

Reload privilege tables now? [Y/n] y
 ... Success!

Cleaning up...

All done!  If you've completed all of the above steps, your MySQL
installation should now be secure.

Thanks for using MySQL!

Follow up by restarting MySQL:

sudo systemctl restart mysqld

Step Three—Install nginx


Once MySQL is all set up, we can move on to installing nginx on the VPS.

sudo pacman -S nginx

nginx does not start on its own. To get nginx running, type:

sudo systemctl start nginx

You can confirm that nginx has installed an your web server by directing your browser to your IP address. You can run the following command to reveal your VPS’s IP address.

curl -s icanhazip.com

Step Four—Install PHP-FPM


In order to process php application, we will need to install php-fpm.

sudo pacman -S php-fpm

Once its installed, start it up.

sudo systemctl start php-fpm

Finally, we need to tell nginx to run php using php-fpm. To accomplish this, first open up the nginx configuration file:

sudo nano /etc/nginx/nginx.conf

Find the location block that deals with php applications and replace the text in the section with the following:

location ~ \.php$ {
      fastcgi_pass   unix:/var/run/php-fpm/php-fpm.sock;
      fastcgi_index  index.php;
      root   /srv/http;
      include        fastcgi.conf;
 }

Save, exit, and restart nginx:

sudo systemctl restart nginx

Step Five—Create a PHP Info Page


We can quickly see all of the details of the new php configuration.

To set this up, first create a new file:

sudo nano /srv/http/info.php

Add in the following line:

<?php
phpinfo();
?>

Then Save and Exit.

Restart nginx

sudo systemctl restart nginx

You can see the nginx and php-fpm configuration details by visiting http://youripaddress/info.php

Your LEMP stack is now set up and configured on your virtual private server.

Step Six—Configure the Daemons to Start at Boot


To ensure that all of the LEMP programs start automatically after any server restarts:

sudo systemctl enable nginx mysqld php-fpm

With that, LEMP is installed.