Work In Progress: Storing PHP sessions in Redis

Hello all! I’ve looked at the documentation for Trellis, and there doesn’t currently seem to be an official way of storing PHP sessions in Redis. Using Memcached for PHP sessions only seems kind of meaningless, so I decided to give storing them in Redis a try!

I’ve managed to get it to work and I’m posting here before making a pull request.

How to try it out:

  1. Open trellis/roles/wordpress-setup/templates/php-fpm-pool-wordpress.conf.j2 and add this at the bottom:
{% if redis_sessions %}
php_value[session.save_handler] = redis
php_value[session.save_path] = "tcp://{{ redis_host }}:{{ redis_port }}?database={{ redis_database }}&prefix=PHPREDIS_SESSION:{% if redis_password %}&auth={{ redis_password }}{% endif %}"
{% endif %}

(Maybe using an else if with the memcached one would be better? Otherwise inattentive users might add both)

  1. Open trellis/group_vars/all/main.yml (or the specific one for testing, staging, etc) and add this:
    redis_sessions: true

  2. Run trellis provision development

  3. Visit the site, add some sessions etc.

  4. Open Redis Insight and check if the sessions are being added to Redis as they should.

Questions for people smarter than me:

  1. Is there a reason that Memcached is used for this by default rather than Redis? Basically, am I missing something here? Is using Redis for PHP sessions a bad idea?
  2. Anything that could be improved about the save_path? I’m currently using tcp but it seems like using “redis_unixsocket” should be possible. However, I can’t get it to work. This for example isn’t working:
    php_value[session.save_path] = "unix://{{ redis_socket_path }}?database={{ redis_database }}&prefix=PHPREDIS_SESSION:{% if redis_password %}&auth={{ redis_password }}{% endif %}"
    Any ideas for getting this to work is welcome!

Thanks in advance for any and all feedback!

I just put up a PR that adds this as a built-in option, mirroring the existing memcached_sessions pattern:

Would appreciate if you could test it out:

redis_sessions: true

Sessions default to Redis database 1 so they stay separate from your object cache on database 0. If you have redis_requirepass set, auth is included automatically.

Why Memcached as the default? Memcached was the lighter-weight option. But if you’re already running Redis for object caching, there’s no real downside to using it for sessions too. Redis has an advantage here since it supports persistence, so sessions can survive a service restart.

Unix sockets: The php-redis session save handler expects the unix:///path/to/socket prefix format (three slashes). Trellis already configures the socket at /var/run/redis/redis.sock and adds www-data to the redis group, so permissions should be fine. The PR currently uses TCP to keep things simple and consistent with the Memcached implementation, but socket support could be added as a follow-up.

Appreciate the answers!

I’ve been running it on database 0 with “unix:///” since I figured out how to do it since Thursday last week. No issues whatsoever on a website with 100k monthly visitors.

Then again, there isn’t much that could break. It’s either logged inside of Redis or by WordPress in the default way if that should fail, or so I’ve found in my testing.

knocks on wood

1 Like