Overview

This guide takes you through the steps to configure your Neos website or Flow application to take advantage of Redis as a cache backend.

You will need a project plan which comes with Redis support. If you're not sure, you can log in to one of your project's instances via SSH and display the Redis connection information like so:

env | grep REDIS

If Redis is available, the output should look something like this:

BEACH_REDIS_PASSWORD=… very long password …
BEACH_REDIS_HOST=redis-123abc45-6789-1234-abcd-22913d67eef0

Behind the Scenes

Flow Framework – and by that, of course Neos as well – provides a caching framework which allows for plugging in different cache backends for storing data. By default file system based cache backends are used, which makes Flow and Neos compatible with virtually any hosting environment.

There are, however, a number of reasons for choosing a Redis backend:

  • Redis stores data in memory and can therefore deliver results even faster
  • as soon as you scale your application, you'll want multiple instances to access one common cache storage
  • Redis stores its data independently from your instance's ephemeral storage. User sessions and other session based data would be lost after each deployment if it is stored in the container's file system. Using Redis allows user sessions to "survive" deployments and let Neos editors continue to work

Neos and Flow use various caches for different purposes, including storage for sessions, compiled code and other temporary data. Not all caches make sense to be stored or can be stored in Redis.

Enabling Redis for Neos

Configuring Neos to use Redis is very easy: all it takes is providing the necessary information in a file called Caches.yaml and deploy it as part of your Neos distribution. Instead of hard-coding the host name and password, you'll want to use environment variables which are provided by Beach.

In your Neos project, create a new file Caches.yaml in the global configuration directory of your project. We recommend putting the configuration into Configuration/Production/Caches.yaml.

Then copy and paste the following YAML configuration into your new file:

Flow_Mvc_Routing_Route:
  backend: 'Neos\Cache\Backend\RedisBackend'
  backendOptions:
    hostname: '%env:BEACH_REDIS_HOST%'
    password: '%env:BEACH_REDIS_PASSWORD%'
    port: 6379
    # starting with database 2 here, since 0 and 1 are used and flushed by
    # the core unit tests and should not be used if possible.
    database: 2
    defaultLifetime: 0

Flow_Mvc_Routing_Resolve:
  backend: 'Neos\Cache\Backend\RedisBackend'
  backendOptions:
    hostname: '%env:BEACH_REDIS_HOST%'
    password: '%env:BEACH_REDIS_PASSWORD%'
    port: 6379
    database: 3
    defaultLifetime: 0

Neos_Fusion_Content:
  backend: 'Neos\Cache\Backend\RedisBackend'
  backendOptions:
    hostname: '%env:BEACH_REDIS_HOST%'
    password: '%env:BEACH_REDIS_PASSWORD%'
    port: 6379
    database: 4
    defaultLifetime: 0

Flow_Session_MetaData:
  backend: 'Neos\Cache\Backend\RedisBackend'
  backendOptions:
    hostname: '%env:BEACH_REDIS_HOST%'
    password: '%env:BEACH_REDIS_PASSWORD%'
    port: 6379
    database: 5
    defaultLifetime: 0

Flow_Session_Storage:
  backend: 'Neos\Cache\Backend\RedisBackend'
  backendOptions:
    hostname: '%env:BEACH_REDIS_HOST%'
    password: '%env:BEACH_REDIS_PASSWORD%'
    port: 6379
    database: 6
    defaultLifetime: 0

Neos_Media_ImageSize:
  backend: 'Neos\Cache\Backend\RedisBackend'
  backendOptions:
    hostname: '%env:BEACH_REDIS_HOST%'
    password: '%env:BEACH_REDIS_PASSWORD%'
    port: 6379
    database: 7
    defaultLifetime: 0

Commit the changes into your Git repository and deploy the changes to your Beach instance. When the instance has been deployed, you can check if the cache configuration is really active by logging in to your instance via SSH and displaying the Flow configuration:

./flow configuration:show --type Caches | grep -A 5 Flow_Mvc_Routing

Flow_Mvc_Routing_Route:
  backend: Neos\Cache\Backend\RedisBackend
  backendOptions:
    hostname: redis-123abc45-6789-1234-abcd-22913d67eef0
    password: … very long password …
    port: 6379
--
Flow_Mvc_Routing_Resolve:
  frontend: Neos\Cache\Frontend\StringFrontend
  backend: Neos\Cache\Backend\RedisBackend
  backendOptions:
    hostname: redis-123abc45-6789-1234-abcd-22913d67eef0
    password: … very long password …

Congratulations! You're now using Redis for the most important Neos caches.

Enabling Redis for Flow applications and Neos plugins

Depending on the packages and caches your Flow application or Neos plugins use, you might want to configure more caches to use Redis as a backend. You can just add these to your Caches.yaml – take care though that you use a "database" value which isn't used by any other cache in your instance.

Caveats

There are some things you need to be aware of when using Redis as a cache backend for Neos and Flow:

Caches must be flushed by Flow

If you'd like to flush all caches, don't fall into the trap of just deleting all files in Data/Tempory. Use Flow's command instead, which not only removes files but also dutifully flushes cache entries of all other cache backends:

./flow flow:cache:flush

Note that force-flushing the caches will not flush the Redis cache, because what Flow does internally is basically deleting the Date/Temporary/* directory:

# This does not flush the Redis cache:
./flow flow:cache:flush --force

Oh, by the way, have you tried this instead?

./flow sys 64738

Redis is only medium-persistent

Even though your Redis cache entries will live longer than the files in your containers, they won't live forever. For example, when we run a cluster upgrade or move cluster nodes to newer machines, the cluster scheduler will need to restart containers, including your Redis server. All cache entries are gone after a restart, but if you really use it as a cache and not as a persistent storage, your application will re-create all needed cache entries without a problem.

Debugging Redis content and status

It is rather easy to look into the Redis server itself. There are two ways, a bare-bones one and a more advanced one.

The bare bones way uses netcat after logging in to your instance using SSH.

$ ssh -J beach@ssh.flownative.cloud beach@instance-….beach

beach@instance-…-qg7jb:/application$ echo $BEACH_REDIS_PASSWORD
oArc…long…password…7Hc7

beach@instance-…-qg7jb:/application$ nc $BEACH_REDIS_HOST 6379
AUTH oArc…long…password…7Hc7
+OK
INFO
$3728
# Server
redis_version:6.0.16
redis_git_sha1:00000000
redis_git_dirty:0
redis_build_id:6d95e1af3a2c082a
redis_mode:standalone

…

# Keyspace
db0:keys=1828,expires=0,avg_ttl=0

QUIT
+OK
^C
beach@instance-…-qg7jb:/application$
  • First you log in to your instance (line 1)
  • Then you fetch and copy the password for your Redis (line 3)
  • Now use nc to connect to Redis (line 6) – you won't get any output, just type your commands now…
  • The next step is to authenticate using AUTH and the copied password (line 7)
  • From now on, you can use any of the Redis commands, e.g. INFO (line 9)
  • When you are done, QUIT and then stop nc with Ctrl-C (line 23)

The more advanced way is to create an SSH tunnel to your Redis via your Beach instance. Then you can use any Redis client by connecting to your local tunnel endpoint. This is similar to how you can access a Beach instance database:

$ ssh -nNT -L 6379:redis-da125679-1234-4cdb-8800-a335023289b5:3306 beach@instance-…

To get the needed data, copy the Redis hostname from your instance details page and fetch the password as described above. Then you can access Redis like this on your machine, after having established tunnel:

$ redis-cli
127.0.0.1:6379>

The next step is to authenticate using AUTH and the copied password. From now on, you can use any of the Redis commands. Feel free to use any other client, of course.