PHP FPM

Posted on 21 2026

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 .php file, 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.