Serve PHP with PHP-FPM and NGINX
https://www.linode.com/docs/web-servers/nginx/serve-php-php-fpm-and-nginx/
Last updated
https://www.linode.com/docs/web-servers/nginx/serve-php-php-fpm-and-nginx/
Last updated
Updated Monday, November 19, 2018 by LinodeWritten by LinodeUse promo code DOCS10 for $10 credit on a new account.Try this Guide Contribute on GitHub
Report an Issue | View File | Edit File
The PHP Fast Process Manager is a FastCGI handler for PHP scripts and applications. It’s commonly paired with web servers to serve applications which require a PHP framework, such as web forums or login gateways, while the web server returns HTML, JavaScript, and other non-PHP content.
You will need a working NGINX setup. If you do not already have that, complete Part 1 of our Getting Started with NGINX series: Basic Installation and Setup.
You will need root access to the system, or a user account with sudo
privileges.
Update your system’s packages.
Install the PHP process manager. On CentOS, Debian, and Ubuntu, the package name to install is php-fpm
.
You can verify the PHP-FPM service is running with:
Depending on your distribution and PHP version, the PHP configuration files will be stored in different locations. This guide is using PHP 7.0 from Ubuntu’s repositories on Ubuntu 16.04 as an example, and the /etc/php/7.0/fpm/pool.d/www.conf
and /etc/php/7.0/fpm/php.ini
files are what we’ll be modifying.
Find those full file paths using a find
command:
The output should look similar to:
The listen.owner
and listen.group
variables are set to www-data
by default, but they need to match the user and group NGINX is running as. If you installed NGINX using our Getting Started with NGINX series, then your setup will be using the nginx
user and group. You can verify with:
The output should be similar to:
This shows the NGINX master process is running as root
, and the worker processes are running as the nginx
user and group. Change the listen
variables to that:
When pairing NGINX with PHP-FPM, it’s possible to return to NGINX a .php
URI that does not actually exist within the site’s directory structure. The PHP processor will process the URI, and execute the .php
file, because its job is to process anything handed to it by NGINX. This presents a security problem.
It’s important to limit what NGINX passes to PHP-FPM so malicious scripts can’t be injected into return streams to the server. Instead, the request is stopped, possibly then resulting in a 404. There are multiple ways to do this (see the NGINX wiki) but here we chose to specify the setting in PHP-FPM rather than in NGINX’s configuration.
You’ll notice that ;cgi.fix_pathinfo=1
is commented out by default. Setting it to 0
and uncommenting it will enforce the configuration should there be any upstream changes in the default value in the future.
Restart PHP-FPM to apply the changes:
Again pulling from Part 1 of our NGINX series, we’ll start with a basic Server Block for a static HTTP page being served from /var/www/example.com
. Replace example.com
with your site’s domain or IP address, and the root
directive with your site’s root directory./etc/nginx/conf.d/example.com.conf
To the Server Block above, add a location
block containing the PHP directives. You should then have:/etc/nginx/conf.d/example.com.conf
This is just a bare minimum to get PHP-FPM working and you will want to configure it further for your specific needs. Some further points about the configuration above:
The location ~* \.php$
means that NGINX will apply this configuration to all .php
files (file names are not case sensitive) in your site’s root directory, including any subdirectories containing PHP files.
The *
in the ~* \.php$
location directive indicates that PHP file names are not case sensitive. This can be removed if you prefer to enforce letter case.
The fastcgi_pass
location must match the listen =
value in /etc/php/7.0/fpm/pool.d/www.conf
. It is preferable for performance reasons for PHP-FPM to listen on a UNIX socket instead of a TCP address. Only change this if you require PHP-FPM use network connections.
Using $document_root
in the SCRIPT_FILENAME
parameter instead of an absolute path is preferred by NGINX’s documentation.
Here’s a variation of the location
block above. This includes an if
statement which disallows the FPM to process files in the /uploads/
directory. This is a security measure which prevents people from being able to upload .php
files to your server or application which the FastCGI process manager would then execute.
This only applicable if you allow users to upload or submit files to your site. Change the name of the directory from uploads
to whatever suits your need./etc/nginx/conf.d/example.com.conf
Reload NGINX:
Create a test PHP file so you can verify FPM is working. In the Server Block above, our site is being served from /var/www/example.com
, so we’ll create a test file there:
Access test.php
from a web browser, using your site’s domain or Linode’s IP address. You should see the PHP configuration page:
You may wish to consult the following resources for additional information on this topic. While these are provided in the hope that they will be useful, please note that we cannot vouch for the accuracy or timeliness of externally hosted materials.