FastCGI Server

FastCGI Server

README

This is a guide for the installation and configuration of a fastcgi server called php-fpm for a local development environment (even so this guide can be used to install it in a production server with the same functionality).

The variables, commands and overall process that will be presented here are based on a Debian based distribution and with a few modifications you can be able to accomplish the same result in other systems.

PHP-FPM (FastCGI Process Manager) is an alternative PHP FastCGI implementation with some additional features useful for sites of any size, especially busier sites. These features include:

  • Adaptive process spawning (NEW!)
  • Basic statistics (ala Apache’s mod_status) (NEW!)
  • Advanced process management with graceful stop/start
  • Ability to start workers with different uid/gid/chroot/environment and different php.ini (replaces safe_mode)
  • Stdout & stderr logging
  • Emergency restart in case of accidental opcode cache destruction
  • Accelerated upload support
  • Support for a “slowlog”
  • Enhancements to FastCGI, such as fastcgi_finish_request() - a special function to finish request & flush all data while continuing to do something time-consuming (video converting, stats processing, etc.)

Documentation

It’s assumed that this proxy server will be used with a nginx server, so it could be helpful for you to read this other guide before continue Nginx Server.

FastCGI becomes more and more popular these days as people tend to realize that light HTTP servers (lighttpd, nginx and the like) are much more efficient on heavy-loaded frontends than traditional Apache.

However the FastCGI implementation in sapi/cgi requires third-party applications like spawn-fcgi or mod_fcgi to manage its processes and is a core implementation of FastCGI protocol lacking a lot of features that are crucial for many complex real-life applications.

Installation

PHP-FPM is finally in PHP core. It is based off of the 0.6.x series in Launchpad, and is now the officially supported release. All the different versions of PHP-FPM are available for download through the official website PHP-FPM - FastCGI Process Manager.

If you have php >= 5.3.3 then you can add FastCGI support to your installation following the instructions in these pages:

However, if your php version is bellow 5.3.3 its better to install the package php5-fpm through the software manager available in your system. This is an example in a Debian based system:

$ sudo apt-get install php5-fpm

Configuration

Nginx can be used to route requests to FastCGI servers which run applications built with various frameworks and programming languages such as PHP.

The most basic nginx configuration to work with a FastCGI server includes using the fastcgi_pass directive instead of the proxy_pass directive, and fastcgi_param directives to set parameters passed to a FastCGI server. Suppose the FastCGI server is accessible on localhost:9000. The resulting configuration would be:

server {
    location / {
        fastcgi_pass  localhost:9000;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param QUERY_STRING    $query_string;
    }

    location ~ \.(gif|jpg|png)$ {
        root /data/images;
    }
}

This will set up a server that will route all requests except for requests for static images to the proxied server operating on localhost:9000 through the FastCGI protocol.

Content-Type

Until now nginx can’t serve PHP pages, instead it will force the download of every file with the extension .php as you can see here:

$ curl --head 'http://127.0.0.1/phpinfo.php'
  HTTP/1.1 200 OK
  Server: nginx/1.4.4
  Date: Sun, 01 Dec 2013 02:11:29 GMT
  Content-Type: application/octet-stream
  Content-Length: 16
  Last-Modified: Sun, 01 Dec 2013 02:11:25 GMT
  Connection: keep-alive
  ETag: "529a9acd-10"
  Accept-Ranges: bytes

We will need to configure the directive listen located at /etc/php5/fpm/pool.d/www.conf and change its value so it looks like this listen = 127.0.0.1:9000. Then we will start the FastCGI server like this:

$ nano /etc/php5/fpm/pool.d/www.conf
$ grep 'listen = ' /etc/php5/fpm/pool.d/www.conf 
  ;listen = /var/run/php5-fpm.sock
  listen = 127.0.0.1:9000
$ sudo service php5-fpm start
$ sudo service php5-fpm status
  [ok] php5-fpm is running.

Then we will add some rules in the nginx configuration file to render PHP files, these rules should be inside the context server, it is possible that you already have other rules inside that context and you can leave them as they are as long as they don’t generate conflicts with the directive location.

http {
    server {
        location ~ \.php$ {
            # NOTE: You should have "cgi.fix_pathinfo = 0;" in php.ini
            include fastcgi_params;
            fastcgi_split_path_info ^(.+\.php)(/.+)$;
            fastcgi_pass 127.0.0.1:9000;
            fastcgi_index index.php;
            fastcgi_param SCRIPT_FILENAME /opt/nginx/html$fastcgi_script_name;
        }
    }
}

After this reload the nginx configuration file and check that the files with a PHP extension is responding with a content-type of text/html instead of application/octet-stream:

$ sudo /opt/nginx/sbin/nginx -s reload
$ $ curl --head 'http://127.0.0.1/phpinfo.php'
  HTTP/1.1 200 OK
  Server: nginx/1.4.4
  Date: Sun, 01 Dec 2013 02:34:28 GMT
  Content-Type: text/html
  Connection: keep-alive
  X-Powered-By: PHP/5.5.5-1
Do you have a project idea? Let's make it together!