Skip to main content

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

PHP-FPM status

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.

Enroll
Enjoying the course content? Enroll today to keep track of your progress, access premium lessons and more.