Using w3tc (W3 Total Cache) cache with wordpress bedrock

As anyone who ever seriously developed with wordpress – it is not the platform that is necessarily known for solid software architecture and modern development practices. WordPress does absolutely excel in other areas though – such as UI and ease of use. It’s end-user-friendliness (but let’s not mistake end-users with software developers) is unparalleled, which is probably why despite there being many competing CMS’es and publishing platforms over the years – wordpress is still the king that rules the blogging industry.

What is bedrock and what does it have to do with wordpress?

Roots bedrock is a project that intents to solve some of those software architecture issues that stand in the way of modern development flow with wordpress. Im not going to go into details and pros and cons of bedrock -> you can read more about it on their project website.

Why w3tc doesn’t play well with bedrock

Out of the box vanilla Wordpess setup implies we’re allowing WordPress to write into project directory. Now – modern PHP development practices call for quite the opposite -> data and code should be separate and code should NEVER be written to. This is one of the things that bedrock tries to enforce with it’s directory structure.

W3tc however – just by the nature of what it needs to do – does need to write somewhere on filesystem and since plugin is oriented first and foremost on vanilla wordpress users -> it does so by writing into wp-content directory that is writable in vanilla wordpress (called app directory in bedrock).

Installing w3tc with bedrock

With bedrock we typically install plugins by using packages from wpackagist (aka wordpress packagist). Which is the way to do modern PHP development these days. Typically your composer.json file would include an entry like this:

  "require": {
    "wpackagist-plugin/w3-total-cache":"2.1.0"
  },

After that you can simply run composer update and this should pull w3tc plugin into bedrock. Now if you head on over to plugins -> you should see W3 total cache plugin there.

Now this is all nice and good – and w3tc got installed, just not activated.

Once u go to activate it you’ll be presented with several error messages, something like this:

Transcript:

W3 Total Cache Error: Files and directories could not be automatically created to complete the installation.
Please execute commands manually	
or use FTP form to allow W3 Total Cache make it automatically.	
Execute next commands in a shell:
cp /var/www/bytepursuits/bedrock/web/wp-content/plugins/w3-total-cache/wp-content/advanced-cache.php /var/www/bytepursuits/bedrock/web/wp-content/advanced-cache.php
mkdir /var/www/bytepursuits/bedrock/web/wp-content/cache
chmod 777 /var/www/bytepursuits/bedrock/web/wp-content/cache
mkdir /var/www/bytepursuits/bedrock/web/wp-content/w3tc-config
chmod 777 /var/www/bytepursuits/bedrock/web/wp-content/w3tc-config

What you shouldn’t do – is follow w3tc instructions above as you DO NOT want to write into app directory under any circumstances. Code should be stateless – amiright.

What should we do instead then?

Not to waste your time here – solution is symlinking those instead.

It is somewhat annoying of course, however luckily there is only a total of 5 assets that w3tc requires to be under bedrock’s app directory: 3 files and 2 directories. Also 2 of those files are optional – only add those if you want to use database and object-cache. So luckily damage is limited:

  • advanced-cache.php – file. (required)
  • db.php – file (optional). only symlink if you plan to enable database cache.
  • object-cache.php – file (optional). Only symlink if you plan to enable object cache
  • cache directory
  • w3tc-config directory

One very important thing to remember with symlinking -> if you have multiple environments. Such as – if you’re developing locally and then deploying to other environments, these symlink destinations must exist in all environments.

Depending on how you do your bedrock setup. With dockrer/docker-compose – I typically mount a directory from host into bedrock container, ex /custom-wp-w3tc in this case:

    volumes:
      - ${CODE_DIR}:/var/www/bytepursuits
      - ${FS_DIR}/wp/sessions:/var/lib/php/sessions
      - ${FS_DIR}/wp/logs:/var/log/apache2
      - ${FS_DIR}/wp/uploads:/custom-wp-uploads
      - ${FS_DIR}/wp/w3tc:/custom-wp-w3tc

And then all these 5 w3tc assets could juts be symlinked to /custom-wp-w3tc inside container (and can point to whatever directory you mounted from the host – giving you some flexibility).

Easy enough right?

What is the difference between database cache and object cache in w3tc?

You might be wondering this as I did.

It is a very good question indeed. Object cache is sometimes called transient objects cache – and is used to cache results of complex database queries. Object cache is built into WordPress code – and w3tc simply allows us to control the storage backend for it. I’d certainly use something like redis to store these.

Database cache – is something ptovided by w3tc plugin (wordpress doesn’t do this by itself) instead and allows us to cache results of simple database queries, such as simple SELECT calls. It is not immediately clear to me why wordpress chose not to provide this functionality natively, but since these are simple queries perhaps benefit is not worth it? Certainly do some load-testing and decide for yourself if you need this.

The end. Thank you for reading.

Leave a Comment