PHP FPM
PHP-FPM is one of those things that quietly sits in the background of a Linux web server until it breaks, at which point you suddenly become very aware of it.
At a basic level:
- Nginx handles the web requests
- PHP-FPM processes the PHP
- the browser gets the result
Nginx itself does not execute PHP. It hands the request off to PHP-FPM over a socket, PHP does its thing, then Nginx returns the output back to the client.
Installing PHP-FPM
On Ubuntu:
sudo apt install php7-fpm
That installs the PHP FastCGI Process Manager and starts the service.
You can check it’s running with:
systemctl status php7-fpm
PHP configuration
There are a few things worth changing early.
php.ini
Edit:
/etc/php/7.0/php.ini
Set:
cgi.fix_pathinfo=0
This stops PHP trying to guess paths it shouldn’t be guessing.
PHP-FPM pools
Pools define how PHP workers are grouped and managed.
The default pool usually lives here:
/etc/php5/fpm/pools.d/www.conf
A couple of useful settings:
pm.status_path = /fpm_status
catch_workers_output = yes
The first gives you a status endpoint. The second makes debugging less miserable when PHP decides to complain.
Restarting PHP-FPM
After changes:
sudo service php5-fpm restart
Or if you’re on a newer system:
sudo systemctl restart php7-fpm
Ubuntu naming around PHP services has always had a bit of “surprise mechanics” energy to it.
Nginx and PHP
There are really two parts to this.
First, Nginx needs to know where PHP-FPM lives.
Then it needs to know when to pass requests over to it.
Defining the PHP backend
Create something like:
/etc/nginx/http-conf.d/php-backend.conf
upstream php-backend {
server unix:/run/php/php7.0-fpm.sock;
}
fastcgi_buffers 128 8k;
That socket path is the important bit. It’s how Nginx talks to PHP-FPM.
If the socket path is wrong, PHP simply stops existing from Nginx’s perspective.
The PHP handler
Now tell Nginx what counts as a PHP request.
Example:
/etc/nginx/php-handler.conf
location ~ \.php$ {
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
include fastcgi_params;
fastcgi_index index.php;
fastcgi_pass php-backend;
}
This basically says:
“if it’s a
.phpfile, hand it to the PHP backend”
Simple enough.
FastCGI parameters
The fastcgi_params file passes request information into PHP.
Things like:
- request method
- query strings
- paths
- HTTPS status
- remote IPs
Without it, PHP has very little context about the request it’s handling.
One particularly important line:
fastcgi_param HTTP_PROXY "";
That mitigates the old httpoxy vulnerability, which is one of those wonderfully named internet problems that sounds fake until it ruins your afternoon.
Restarting Nginx
Whenever you change Nginx config:
sudo service nginx restart
Or preferably:
sudo nginx -t
sudo systemctl reload nginx
Because testing the config before restarting it is one of those habits that saves you from yourself later.