Nginx proxy caching with multiple php pools and WordPress
I like Nginx and am always looking for faster better ways to serve websites.
A few years ago we found a script called Tuxlite which opened up the idea, to us, of using multiple PHP pools, using Unix socks, to serve multiple websites without everyone being under the same www-data user. this provided both security and separation of configurations which we wanted without having to setup a new server for every website.
The idea being, you configure Nginx to serve and respond to multiple different domain names, using separate configs under sites available, and each of these config files has a line
which relates to a specific php-fpm pool for that user alone to use.
The result is we have control over the resources used as well as separate configs for both Nginx and php-fpm for each user.
Move onto 2019 and I find a writeup by the wonderful Dave Hilditch at WP Intense who has put together a great guide to utilise the latest and fastest stack for hosting WordPress sites.
It utilises PHP7.2 fpm, Mysql 8 and most importantly it uses the Nginx Proxy cache so that your caching for your WordPress website is now handled directly by Nginx instead of by a WordPress based caching plugin. (in case you don’t know that means its quick, like Varnish cache quick)
Speed tests were very encouraging and this stack configuration provided some much needed configuration tweaks for handling caching while allowing things such as logged in users or WooCommerce baskets to skip the cache which Dave had included as snippets and they can be included in your config files easily.
One issue for us was this server setup was designed to only serve one site per VPS/Server at a time.
So no pool config or detail about managing Nginx caches for multiple sites effectively.
Now if you are not using Pools for your php-fpm then this likely wont affect you as everything runs under www-data as a user across the server and you will be fine.
For us we had one major grinding issue which was,
- When you are serving multiple sites
- When each site has its own pool.d conf file
- When Nginx configs specify these pools as the php user
- When you have successfully setup seperate cache directives for each site so they have their own caches.
You cannot use the very well made Till Kruess Nginx Cache plugin for WordPress because it cannot remove the cached files as they are owned by www-data (nginx) when you are running php as a different pool user.
I tested adding the user that owns the data and the pool to the www-data group but while this works and I can now map the /run/cache/mysite cache folder within the nginx plugin (we used /run/ as the base for our cached files as this is a tmpfs file and so runs in ram not hdd based) this means that user now has www-data group access which is not really a good idea.
I found a comment on an old blog post that linked through to another blog post and then to the archive.org version of the post as the original blog left the internet which provides the best solution I have seen so far for this uncommon issue.
Adding bindfs allows you to mount the cache directory somewhere else and access it as a local user. But the folder itself and its contents are still actually owned by www-data.
So both users essentially own it but it is mounted for the local user to be able to edit and it appears as if that user owns the folders and files. which is precisely what we need for the Nginx plugin to work within WordPress correctly.
In our case we would
Create the mount point
mkdir -p /home/freduser/sites/website1/cache
Chown this folder (assuming freduser already owns the /sites/website1 folder)
chown -Rf freduser:freduser /home/freduser/sites/website1/cache
Then Chmod the folder
chmod -Rf 770 /home/freduser/sites/website1/cache
This creates the folder and allows freduser essentially full permissions to edit/add/modify files.
Within Fstab (edit /etc/fstab) we add an entry creating the relationship between the mount point in /home/freduser/sites/website1/cache and the actual folder containing the files which is /run/cache/website1
bindfs#/run/cache/website1 /home/freduser/sites/website1/cache fuse force-user=freduser,force-group=freduser,create-for-user=www-data,create-for-group=www-data,create-with-perms=0770,chgrp-ignore,chown-ignore,chmod-ignore 0 0
This creates the relationship which will automatically mount on restart of the server.
While we are testing we can manually mount it by using
and thats it.
We now have the /run/cache/website1/ files available and appearing to be owned by freduser (and specifically php can read and write to them). If freduser makes a change the change is also made in /run/cache/website1/ and the files there are actually owned by www-data and can be accessed and modified /used by Nginx proxy cache as intended.
Multi user with seperate caches and seperate phpfpm pools.
Now to make a script which sets that all up automatically………