For all of the benefits that come with using Bedrock it is sometimes at odds with the way that vanilla WordPress works. I recently ran into issues when adding a caching plugin to a Bedrock based site which was deployed by Capistrano.
Unlike most plugins, WP Super Cache has to make changes to other files in your site. It has to make changes to your
wp-config.php and also add new files and folders to
app/web. Some of these changes are useful configuration options, allowing you to easily port your settings between environments. Unfortunately there are a number of hardcoded filesystem paths interspersed in these files, which don’t translate so easily between environments.
If you commit these files into your git repo then the paths will be wrong when you deploy, but if you don’t you’ll have to reconfigure the plugin after each Capistrano deploy to have them rebuilt.
Working around the issues
It’s worth saying upfront that this might not be totally in the spirit of how Bedrock is supposed to be used, the following is my pragmatic approach to getting it working in a maintainable manner.
Setup locally and modify .gitignore
As normal, add the plugin to your composer file and do a
composer update. By enabling the plugin locally all the changes to the filesystem become apparent. After enabling, configure the plugin from the UI for the settings you need. The following files will now have been edited/created:
.gitkeep file to
web/app/cache and then edit your projects
.gitignore file, adding the following lines:
Commit all the changes to your repo.
Move environmental configuration into .env
WP Super Cache adds a couple of lines to your
app/wp-config.php file, by default your file will now look something like this:
<?php // WP Super Cache define('WPCACHEHOME', '/absolute/path/to/wp-super-cache'); //Added by WP-Cache Manager define('WP_CACHE', true); //Added by WP-Cache Manager /** * Do not edit this file. Edit the config files found in the config/ dir instead. * This file is required in the root directory so WordPress can find it. * WP is hardcoded to look in its own directory or one directory up for wp-config.php. */ require_once(dirname(__DIR__) . '/vendor/autoload.php'); require_once(dirname(__DIR__) . '/config/application.php'); require_once(ABSPATH . 'wp-settings.php');
The absolute path here is a problem but Bedrock makes use of
.env files, so we can abstract this away to an environmental variable. It’s important to note that the
getenv function only gets setup after the
config/application.php file is included. So to achieve what we want we need to move the
define statements down the file, to look something like this:
<?php /** * Do not edit this file. Edit the config files found in the config/ dir instead. * This file is required in the root directory so WordPress can find it. * WP is hardcoded to look in its own directory or one directory up for wp-config.php. */ require_once(dirname(__DIR__) . '/vendor/autoload.php'); require_once(dirname(__DIR__) . '/config/application.php'); // WP Super Cache define('WPCACHEHOME', getenv('WPCACHEHOME')); //Added by WP-Cache Manager define('WP_CACHE', true); //Added by WP-Cache Manager require_once(ABSPATH . 'wp-settings.php');
You can now add the path to the WP Super Cache plugin to your
.env file using the key
We also need to perform a similar task in
web/app/wp-cache-config.php and change the
$cache_path definition so that it too comes from
.env. Look for the line similar to:
$cache_path = '/absolute/path/to/web/app/cache'; //Added by WP-Cache Manager
and replace it with:
$cache_path = getenv('CACHE_PATH'); //Added by WP-Cache Manager
As before, we can now add
CACHE_PATH to our
Commit the changes to these two files to your git repo.
Note: WP Super Cache is quite agressive about changing these values back to what it thinks they ought to be, it appears to happen when you disable/enable the plugin. Be careful to check you don’t commit these changes into your repo later in the project!
Add cache folder to shared folder
Our websites are deployed via Capistrano by a low privileged system user
deploy. We have the Apache user added to the
deploy group, which means we want all files to be created with both the user and group
deploy. We use the
chmod sticky bit to ensure that all new files retain the right permissions. Critically, both the
deploy and Apache user need write access to all files. Apache so that users can uploaded assets from the UI and
deploy so that we can remove old releases.
Ordinarily WordPress respects these settings when files are uploaded from the UI into the
shared folder and everything just works. WP Super Cache however does not obey these settings when building cached assets and instead only the Apache user has write access.
Ideally, we wouldn’t want to have to do this but to work around this you can add
web/app/cache to the list of linked directories. This way the cache files are persistent across deploys so your
deploy user never needs to clean them out, this job can be left to the Super Cache UI.
To do this, add the following line to your Capistrano
set :linked_dirs, fetch(:linked_dirs, ).push('web/app/cache')
Modify the Super Cache plugins path (optional)
If you use the optional plugins for WP Super Cache to extend its functionality then you may want to consider changing where these are stored. By default they live within the WP Super Cache plugin folder, which becomes an issue if you need to add a customisation.
First edit your
web/app/wp-cache-config.php file again and find where
$wp_cache_plugins_dir is set, change this to be:
$wp_cache_plugins_dir = WP_CONTENT_DIR . '/sc-plugins';
Then create the folder
web/app/sc-plugins and place your custom code in there.
It’s worth noting that historically I’ve much more experience with W3 Total Cache but for this particular project I ran into a separate issue where W3TC didn’t like being run from an
Alias in the VirtualHost. As it turned out it seems that WP Super Cache is easier to fit into the Bedrock/Capistrano model but I’m sure with some work the same could be achieved with W3TC.