Use Redis cache with Bedrock and Trellis

Hi,

I’m using this plugin for a woocommerce site:

But I’ve got some problems with the settings file that this plugin generates:
site/web/app/object-cache.php

The problem is that I don’t want this file to be checked in with git/version control because if I disable the plugin in local env and commit the file changes. The file will be considered to be deleted and then also be deleted on staging or production when I deploy.

So right now, after each deploy I have to check if the plugins is deactivated and also flush the redis cache each time. Because things like Product Attributes disappears when i deactivate redis cache.

I’m doing this wrong or do someone experienced the same issue?

Thanks for any kind of reply or help on this.

/Jonas

1 Like

@JulienMelissas and I use(d) WP Redis – WordPress plugin | WordPress.org . I don’t recall having that file change issue. Not sure how much that helps, I haven’t worked with wp-redis and an ecommerce site, so haven’t seen Product Attributes disappear, but nothing should break without using a cache. If you have to do something with each deploy, you should add some code into your trellis repo for it. For example, I have this for another obj cache plugin I used

https://github.com/partounian/trellis/blob/project-template/deploy-hooks/finalize-after.yml
then in group_vars/staging/wordpress_sites.yml in cache I would set wp_lcache: true if I wanted it. It looks like cache:

cache:
      enabled: true
      wp_lcache: false

https://discourse.roots.io/t/any-information-for-scaling-a-wp-website/14319

1 Like

I’ve never had to deal with the file change issue, but my local .env (flywheel) has Redis built in, so I just use that.

Like @partounian said, nothing should break at all without the cache, so I honestly doubt a disabled cache plugin is the cause of things disappearing.

I just set up Trelis with Redis (using the trellis-redis role) and installed the WP Redis plugin:


Static pages already load very fast with Trellis, but dynamic pages (like shop pages/filters/complex admin areas) won’t enjoy the speed up of nginx microcaching.
Using the redis object cache resulted in a very significant speed up, both in development (docker) and production (Trellis on Ubuntu 20).

1 Like

So I got this installed, and the plugin activated, but my server still says (in Query Monitor)

The Redis extension for PHP is installed but is not in use by WordPress

Are there additional steps you had to go through to make the plugin actually use Redis?

Yes, you have to set some parameters in the Bedrock config file.
The usage of configuration for that plugin makes it ideal for Bedrock sites.

Bedrock site file config/environments/production.php:

// Redis cache server (WP Redis plugin)
$_SERVER['CACHE_HOST']        = 'localhost';
$_SERVER['CACHE_PORT']        = 6379;
$_SERVER['CACHE_PASSWORD']    = '';
$_SERVER['WP_CACHE_KEY_SALT'] = 'my-site-1'; // salt to prevent collisions of cached data between different sites
$_SERVER['CACHE_DB']          = 2; // redis DB index, which can be used as additional means of separating cached site data

You can use different configuration for different environments of course, which is very useful:
For production I use the configuration above (locally running redis instance without a password (well, one could add one)), and for development I use a docker container setup with a redis container instead (no salt/DB index needed as there is one redis container per site), which also dramatically improves performance (noticeable even on native WSL 2 file system).

The plugin also offers wp CLI tool commands, which makes it futher useful for Bedrock app-style usage. You can use it to quickly check the cache status and stats and purge the cache.

1 Like

I made a little guide for setting up object caching (Redis) with Bedrock + Trellis:

5 Likes

Thanks for the quick reply and guide … in the end I wasn’t able to get it going by your method but you did point me in the right direction.

Don’t mean to derail or confuse the thread so I’ll try to cover everything I did, your milage may vary.


How I got Redis working with Trellis:

  1. Installed the wp-redis plugin to Bedrock.

In ./site

composer require wpackagist-plugin/wp-redis ^1.1.1
  1. Add trellis-redis role to Trellis. The current version of the marksabbath.trellis_redis repo seems incompatible with my version of Ansible. Someone has a PR for a fix but it’s not yet merged. Luckily you can use that version of your source though.

In ./trellis/requirements.yml

- name: trellis-redis
  src: https://github.com/im-mortal/trellis-redis
  type: git
  version: update/apt
  1. Add the role to ./trellis/dev.yml and ./trellis/server.yml
roles:
  ...
  - { role: trellis-redis, tags: [redis] }
  1. Install the new role (you might need to add a --force flag). In ./trellis/
ansible-galaxy install -r requirements.yml
  1. Re-provision and redeploy the server.

You should now have the WP Redis plugin installed on staging/production. If you have Query Monitor installed (and you should) it’ll say that Redis is available but not in use.

When the WP Redis plugin does its thing, it creates a file symlink. But this will be overwritten with each deploy. So the last step is automating that symlink.

  1. Add to ./trellis/roles/deploy/hooks/finalize-after.yml
- name: Enable Redis
  shell: wp redis enable
  args:
      chdir: "{{ deploy_helper.current_path }}"

You should now have Redis caching working, even after a fresh deploy. Again, confirm this with Query Monitor.


While this worked for me, it’d be easy to overwrite all this config when upgrading Trellis :confused:

5 Likes

Many thanks for sharing your insights + setups @strarsis & @Simeon, much appreciated…!

I went ahead and got Redis to work, a few thoughts / additions regarding the setup:

The forked Ansible role https://github.com/im-mortal/trellis-redis was a great starting point for me but there were a few things I needed to add / tweak so I forked that one as https://github.com/E-VANCE/trellis-redis.

  • The version-specific PHP package is missing, thus I couldn’t get Redis to work. Added this to /tasks/main.yml
- name: Install php-redis (version specific)
  apt:
    pkg: php7.4-redis
    state: present
    update_cache: true
  notify: Restart php-fpm

NOTE: Could / should use a version-placeholder for upwards compatibility…

  • The default Redis-config only assigned 128mb as redis_maxmemory (which might be sensible, not sure as of now) but also set redis_maxmemory_policy to noeviction which makes Redis return a write error once the memory limit has been reached… Thus:
# Max memory values
redis_maxmemory: 2gb
redis_maxmemory_policy: volatile-ttl
redis_maxmemory_samples: 5

NOTE: See this great article regarding the memory aspects as well as the ansible-redis readme which has extensive explanations on the config variables / parameters

  • Setting the WP_REDIS_DEFAULT_EXPIRE_SECONDS constant via Bedrock’s config/application.php allows for a sensible key expiration, see #263 in WP Redis
  • Monitor the memory usage and check for plugins that put a great load on Redis, those can be excluded via the designated wp_cache_add_non_persistent_groups-function in WP Redis
4 Likes

Trellis makes use of {{ php_version }}, so something like this?

- name: Install php{{ php_version }}-redis
  apt:
    pkg: "php{{ php_version }}-redis"
    state: present
    update_cache: true
  notify: Restart php-fpm

Well, exactly…! :slightly_smiling_face:

Just incorporated this in the newest release 0.3.0, also edited the php-fpm-handler to address the {{ php_version }}.

2 Likes

Note: Add cache flush command wp cache flush to Trellis deploy task and also to transfer scripts (as for pulling from production to development).

1 Like

I’ve been using trellis-redis in combination with WP Redis for a WooCommerce webshop. Since there’s quite some products with a lot of variations WP Redis drastically improved performance on especially the product archive page. However a weird quirk popped up; a few times already the somehow the products aren’t found (‘No products are found’ - message is showing). Flushing the cache resolves this issue.

Has anyone had similar issues? Where do I even start debugging this?

Maybe this is not caused by the object cache but by nginx microcaching?
More rarely changing pages are held in cache for some requests, although they may need rerendering.
Pages that are individualized or often-changing (as WooCommerce cart, check-out, account pages) should be excluded from microcaching:

Do you have the same issue when you disable the object cache?

We’ve been utilizing microcaching for a while and this hasn’t caused any issues. This quirk first happened after setting up WP Redis.

To me it does seem like the Object Cache is failing somehow as there are no products found, this page should always show all products so there’s no reason nginx should render a page without any products in the first place.

It’s hard to find out what’s going on because it’s only happened 2 times now and I don’t know how to recreate this locally / on staging)