There are no notfications.

This article was last reviewed for Debian 8 (Jessie).

PHP 5 installation and configuration for Nginx using PHP-FPM (Debian, repository)

PHP 5 installation and configuration for Nginx using PHP-FPM (Debian, repository)
Author: Stefán Örvar Sigmundsson
Initial publication:
Last updated:
Written in: English (United Kingdom)

PHP is the world's most popular server-side web development scripting language. The original and primary PHP interpreter implementation is the Zend Engine. This article will demonstrate how to install and configure PHP 5 and PHP-FPM for Nginx on Debian or its derivatives such as Ubuntu and Linux Mint. The scripting language will be configured for the domain name example.org as a virtual server.

PHP-FPM

PHP-FPM (FastCGI Process Manager) is as its name indicates a process manager for PHP over FastCGI. Nginx and PHP can communicate via the FastCGI binary protocol which PHP-FPM implements along with advanced process management features.

PHP-FPM manages processes in what are called pools. A pool is a configurable unit of one or more processes that handle PHP requests. Pools can be optimised in a variety of ways to serve low to high PHP-intensity web sites. Some important features of pools are:

  • Pools are ownable by specified OS users and groups (for security reasons).
  • Pools are limitable to a minimum and maximum number of processes (for CPU performance reasons).
  • Pools are limitable to a maximum number of PHP requests per process before respawning (for RAM performance reasons).
Ideal pool and process combination
Pool Process Single web site Multiple web sites
PHP-intensity PHP-intensity Administrated
Single Single Low Low Together
Multiple High High Together
Multiple Single Impossible[1] Low Separately
Multiple High Separately
  1. ^ A single pool can serve multiple web sites but a single web site can not be served by multiple pools.

Installation

PHP and PHP-FPM can be installed from the official Debian repository using APT:

root@computer:~# apt --assume-yes install php5-fpm

Configuration

PHP-FPM is stopped before beginning the configuration for the sake of simplicity:

root@computer:~# systemctl stop php5-fpm.service

The default log file for PHP-FPM (php5-fpm) is deleted and a new one (error.log) created in a dedicated directory (/var/log/php5-fpm/) for organisational purposes:

root@computer:~# rm /var/log/php5-fpm.log
root@computer:~# mkdir /var/log/php5-fpm/
root@computer:~# touch /var/log/php5-fpm/error.log

A file is created to contain the error log for PHP in a dedicated directory. PHP does not log errors by default but instead embeds them in the web pages where they occur. PHP errors and warnings should not be visible to the world for security reasons.

root@computer:~# mkdir /var/log/php5/
root@computer:~# touch /var/log/php5/error.log

A directory is created to contain the temporary files uploaded to the web server via PHP before they are saved elsewhere or discarded at the end of scripts:

root@computer:~# mkdir /var/tmp/php5/

There is a lot of clutter in the default configuration files even though they are operational. Clearing them will ensure that there is no conflict nor confusion:

root@computer:~# > /etc/php5/fpm/php.ini
root@computer:~# > /etc/php5/fpm/php-fpm.conf

The default pool created by the package is called www. A pool is created with a more descriptive name:

root@computer:~# rm /etc/php5/fpm/pool.d/www.conf
root@computer:~# touch /etc/php5/fpm/pool.d/example.org.conf

The default user and group assumed by the package are called www-data. A user and a group are created with a more descriptive name:

root@computer:~# useradd --comment "PHP" --shell "/usr/sbin/nologin" --system --user-group php

php.ini

The php.ini file contains PHP's primary configuration:

[PHP]

date.timezone = Atlantic/Reykjavik

display_errors = Off

error_log = /var/log/php5/error.log

error_reporting = 32767

log_errors = On

register_argc_argv = Off

session.gc_probability = 0

short_open_tag = Off

upload_tmp_dir = /var/tmp/php5/
[PHP]
Sets the configuration scope for the subsequent directives to PHP.
date.timezone = Atlantic/Reykjavik
The time zone of the server. The time zone (Atlantic/Reykjavik) should be replaced with the relevant time zone.
display_errors = Off
Disables the embedding of PHP errors and warnings in outputed HTML for security reasons.
error_log = /var/log/php5/error.log
A log file (/var/log/php5/error.log) is created to contain PHP errors and warnings.
error_reporting = 32767
A predefined construct (32767) that instructs the interpreter to log all PHP errors and warnings.
log_errors = On
Enables logging of PHP errors and warnings into the log file.
register_argc_argv = Off
Disables a CLI feature unnecessary for most users.
session.gc_probability = 0
Disables the garbage collection process to prevent session data loss. Sessions will have to be removed manually periodically.
short_open_tag = Off
Disables short form open tags for the sake of standardisation.
upload_tmp_dir = /var/tmp/php5/
A directory (/var/tmp/php5/) is created to contain uploaded files temporarily.

php-fpm.conf

The php-fpm.conf file contains PHP-FPM's primary configuration:

[global]

error_log = /var/log/php5-fpm/error.log

include = /etc/php5/fpm/pool.d/*.conf
[global]
Sets the configuration scope for the subsequent directives to global.
error_log = /var/log/php5-fpm/error.log
A log file (/var/log/php5-fpm/error.log) is created to contain PHP-FPM errors and warnings.
include = /etc/php5/fpm/pool.d/*.conf
All process pool declaration files are included.

pool.d/example.org.conf

The pool.d/example.org.conf file contains a process pool declaration:

[example.org]

group = php

listen = /run/php/php5-fpm.socket

listen.group = nginx

listen.mode = 0660

listen.owner = nginx

pm = ondemand

pm.max_children = 5

pm.max_requests = 200

pm.process_idle_timeout = 10s

user = php
[example.org]
Sets the configuration scope for the subsequent directives to example.org.
group = php
The OS user of the process pool.
listen = /run/php/php5-fpm.socket
The socket used by Nginx and PHP-FPM to communicate.
listen.group = nginx
The OS group of the socket. Nginx must use the same group for communication.
listen.mode = 0660
The file system permissions of the socket.
listen.owner = nginx
The OS user of the socket. Nginx must use the same user for communication.
pm = ondemand
Sets the type of process manager.
pm.max_children = 5
Sets the maximum number of child processes.
pm.max_requests = 200
Sets the maximum number of requests processed per child process before respawning to reclaim leaked memory.
pm.process_idle_timeout = 10s
Sets the idle time for child processes before being killed.
user = php
The OS group of the process pool.

Conclusion

Log rotation

The package installs a default logrotate configuration file (/etc/logrotate.d/php5-fpm) that can be customised:

/var/log/php5/*.log /var/log/php5-fpm/*.log
{
	copytruncate
	maxage 365
	missingok
	monthly
	notifempty
	rotate 12
}
/var/log/php5/*.log /var/log/php5-fpm/*.log
Sets the configuration scope for the subsequent section. The pattern matches all files (*) ending with the extension log in the /var/log/php5/ and /var/log/php5-fpm/ directories.
copytruncate
Copy the contents of the log file being rotated into a new file and then truncate the original log file.
maxage 365
Remove log files older than 365 days.
missingok
Do not consider it an error if a log file is missing.
monthly
Perform a log rotation monthly.
notifempty
Do not perform a log rotation on an empty log file.
rotate 12
Perform 12 log rotations before older log files are removed.

Nginx configuration

This article assumes that the Nginx installation is compatible and that its configuration has not been altered significantly.

FastCGI parameters

PHP-FPM requires miscellaneous information that Nginx must pass on to it. The FastCGI parameters can be stored in a file called conf.d/http_fastcgi.conf.

fastcgi_param  CONTENT_LENGTH     $content_length;
fastcgi_param  CONTENT_TYPE       $content_type;
fastcgi_param  DOCUMENT_ROOT      $document_root;
fastcgi_param  DOCUMENT_URI       $document_uri;
fastcgi_param  GATEWAY_INTERFACE  CGI/1.1;
fastcgi_param  HTTPS              $https if_not_empty;
fastcgi_param  QUERY_STRING       $query_string;
fastcgi_param  REDIRECT_STATUS    200;
fastcgi_param  REMOTE_ADDR        $remote_addr;
fastcgi_param  REMOTE_PORT        $remote_port;
fastcgi_param  REQUEST_METHOD     $request_method;
fastcgi_param  REQUEST_URI        $request_uri;
fastcgi_param  SCRIPT_FILENAME    $request_filename;
fastcgi_param  SCRIPT_NAME        $fastcgi_script_name;
fastcgi_param  SERVER_ADDR        $server_addr;
fastcgi_param  SERVER_NAME        $server_name;
fastcgi_param  SERVER_PORT        $server_port;
fastcgi_param  SERVER_PROTOCOL    $server_protocol;
fastcgi_param  SERVER_SOFTWARE    nginx/$nginx_version;

Virtual server

A directive is added to the virtual server to map PHP-FPM to Nginx so that all PHP files be passed on to PHP-FPM for processing:

server
{
	…

	location ~ [^/]\.php(/|$)
	{
		fastcgi_pass unix:/run/php5-fpm.socket;

		include /etc/nginx/conf.d/http_fastcgi.conf;
	}

	…
}
location ~ [^/]\.php(/|$)
A regular expression to locate PHP files.
fastcgi_pass unix:/run/php5-fpm.socket;
The socket to which PHP files will be passed.
include /etc/nginx/conf.d/http_fastcgi.conf;
The file containing the FastCGI parameters to be passed on to PHP-FPM.

Directory indexing

The conf.d/http_index.conf file defines directory index files. If a directory index file exists in a directory and a user navigates to the directory without specifying a particular file within it then the server will return the directory index file instead of an automatically generated index of the contents of the directory by the http_autoindex module or an HTTP 403 response status code.

index index.php index.htm index.html index.xht index.xhtml;

Reinitiation

Nginx is restarted when the configuration is done:

root@computer:~# nginx -s reload

Directory ownership and permissions

The configuration directory should be protected:

root@computer:~# chown --recursive root:adm /etc/php5/
root@computer:~# chmod --recursive 0770 /etc/php5/

The log directories should be protected:

root@computer:~# chown --recursive nginx:adm /var/log/php5/
root@computer:~# chown --recursive nginx:adm /var/log/php5-fpm/
root@computer:~# chmod --recursive 0750 /var/log/php5/
root@computer:~# chmod --recursive 0750 /var/log/php5-fpm/

The temporary upload directory should be protected:

root@computer:~# chown --recursive nginx:nginx /var/tmp/php5/
root@computer:~# chmod --recursive 0770 /var/tmp/php5/

Process manager initiation

PHP-FPM is started when the configuration is done:

root@computer:~# systemctl start php5-fpm.service

See also

External links

This article has additional content here.