Creating the PHP configuration
In this lesson we'll look at the global and per-site PHP configuration. We'll bring the configs into our version controlled repository, and create a new pool configuration for our WordPress site.
Global PHP configuration
PHP's main configuration lives in a php.ini
file. This is where most runtime
parameters and limits are set. This is also where extensions are enabled and
configured.
If you installed PHP-FPM from an official OS package, you likely have two of these: one for PHP (CLI), and a separate one for PHP-FPM.
cd /etc/php/8.3
find . -name php.ini
./cli/php.ini
./fpm/php.ini
If you inspect the files you'll see there's very minor difference or no difference at all. Unless you have a reason to keep these configs separate, I recommend merging them into one for simplicity. Besides, you can still modify most PHP settings in a pool configuration anyway.
sudo rm /etc/php/8.3/cli/php.ini
sudo mv /etc/php/8.3/fpm/php.ini /config/php/php.ini
Add them to your configs repository, don't forget to symlink them back, and
add them to your symlinks.sh
script.
sudo ln -sfn /config/php/php.ini /etc/php/8.3/fpm/php.ini
sudo ln -sfn /config/php/php.ini /etc/php/8.3/cli/php.ini
Let's do the same with our main php-fpm.conf
file:
sudo mv /etc/php/8.3/fpm/php-fpm.conf /config/php/php-fpm.conf
sudo ln -sfn /config/php/php-fpm.conf /etc/php/8.3/fpm/php-fpm.conf
PHP pool configuration
Now we'll need to define a PHP-FPM pool for our site. While you can get away with a single pool for all your sites, I highly recommend having a separate pool for each site. The overhead is minimal, but this allows you to fine-tune various settings, such as the number of PHP workers available to each site.
By default the PHP installation in Ubuntu and other Debian-based distributions
will ship with a pre-configured default pool in /etc/php/8.3/fpm/pool.d/www.conf
.
Let's use this pool as a base for our own pool for uncached.org
:
sudo mv /etc/php/8.3/fpm/pool.d/www.conf /config/php/uncached.org.conf
sudo ln -sfn /config/php/uncached.org.conf /etc/php/8.3/fpm/pool.d/uncached.org.conf
I encourage you to read through this file to better understand what things are available in a PHP-FPM pool configuration context. Most of it is commented out, but some of the things we should definitely change for our future website.
Here's the full contents of my uncached.org.conf
file:
[uncached.org]
user = www-data
group = www-data
chdir = /sites/uncached.org/public_html
listen = /sites/uncached.org/php-fpm.sock
listen.owner = www-data
listen.group = www-data
pm = ondemand
pm.max_children = 8
php_admin_value[sys_temp_dir] = /sites/uncached.org/tmp
php_admin_value[upload_tmp_dir] = /sites/uncached.org/tmp
php_admin_value[session.save_path] = /sites/uncached.org/tmp
php_admin_value[open_basedir] = /sites/uncached.org/:/tmp/
This is a minimal configuration and we'll be adding more things to it as we go along. Let me explain what every line does.
The first line is the INI section for our pool [uncached.org]
. You
can call this whatever you like, but I recommend using something that can
easily be mapped back to the site that's going to use this pool.
Next, we set the user
and group
for this pool to www-data
. This means
that workers spawned in this pool are going to be set to that user/group,
which works well with all of our site files owned by www-data
.
The chdir
line changes the worker's current directory. More of a guard-rail
for relative includes and some old or sloppy PHP code.
The next listen
block defines our socket path, and the owner/group for this
socket. Each pool will have a unique socket, and we'll then configure Nginx
to use this socket for PHP requests.
Our pm
section defines how we're going to spawn workers, and how many workers
we're going to spawn. We'll get into right-sizing and performance tuning in a
future module. For now, the ondemand
mode is always a safe bet, with the
max_children
set to the maximum number of workers you'd like to have for this
site. I have 24 cores on my server, so 8 workers is very conservative for
a single site, but it's still a good starter value.
Finally, we have some php_admin_value
directives. This is a way to define
php.ini
settings exclusively for this pool. In this example I set the temp,
upload, and sessions directory to our tmp
folder, and use the open_basedir
directive to restrict the workers' access to just the site directory and the
system /tmp
since some modules may use that directly.
If you want to change the memory limit, maximum upload size, etc. just for this site and not globally, this is the place to do it.
Let's save this configuration, add and commit everything to our configs repository, and restart PHP-FPM:
sudo systemctl restart php8.3-fpm.service
The pool will not spawn any workers just yet, this is because there is no traffic to our PHP listener. Let's make sure the socket is created in the right place:
ls -al /sites/uncached.org/php-fpm.sock
This socket does not speak the HTTP protocol, so we can't easily test it out with cURL for example. We'll need something that speaks the FastCGI protocol, like Nginx.