Installing and configuring Redis for Symfony takes quite a few steps. So many I’d never remember them all. This article is for myself at a later date as well as anyone else who finds it useful. I’ll be updating this article as I learn more.
This article covers installing and configuring Redis for use for both Session storage and Application cache.
First you need Redis the program itself running. I suggest using Docker so you can quickly spin up Redis containers for experimenting.
If you are not familiar with Docker I suggest you start with this getting started guide.
If you are using docker once you have started a Redis instance test it by trying to use the cli like so
You should see something similar to this.
This means redis is running on 127.0.0.1 (localhost) on port 6379 which is the default port.
With redis-cli running you can further test with the following.
//set a key and value set someKey "some value for the key" //get the value for the key get someKey //view a list of all keys in redis storage keys "*"
In production you need to install Redis or have access to a server running Redis, I’ll cover that in another article.
Install phpredis extension
You will need to install phpredis php extension and configure it. Before you can even do that though, you will need to install another php module php-dev I am using php 7.4 and Ubuntu so to install that I do this.
apt-get install php7.4-dev
This is needed because phpredis use phpize and phpize is included in php-dev.
If you are using another version of php you can search apt repository for this package like this:
apt search php-dev
or for version specific like this apt search phpver-dev
apt search php7.4-dev
Change the version number to match yours.
Next you install the phpredis extension from pecl.
pecl install redis
This is just the extension for the client to interact with your Redis server wherever it is, either local or remote.
Now you must configure PHP to use this extension.
You could add the needed config values to the php.ini config, but the problem is there are two. Yeah one for the cli and one for fpm. I have an easier solution. Create one file and symlink for both cli and fpm.
You will need both configured. As I found out if you configure only fpm your app will work, but when you go to composer install/update/require etc. you will get a cli error about missing such and blah Redis extension blah blah.
If you are running PHP 7.4 on Linux you will want to create a file in the following /etc/php/7.4/mods-available directory named phpredis.ini with the following
session.save_handler = redis
session.save_path = "tcp://localhost:6379?timeout=3&read_timeout=3"
You can find more info here in the phpredis docs.
Once you have created that file you need to symlink to the fpm and cli to let them know the configuration exists.
Run the following commands to symlink.
ln -s /etc/php/7.4/mods-available/phpredis.ini /etc/php/7.4/cli/conf.d/phpredis.ini ln -s /etc/php/7.4/mods-available/phpredis.ini /etc/php/7.4/fpm/conf.d/phpredis.ini
The way this works is php after it reads the php.ini reads in all of the configuration files ( those with .ini extension) from the conf.d directory for either cli if you are using the command line or from fpm for your app. This makes configuring anything you need for php easier than having to open the giant php.ini file, plus you don’t have to worry about ruining one, which I have done easily. Here is a link to the php docs on configuring and .ini files
Now you must restart php fpm for your app to work. On Ubuntu you can do this.
service php7.4-fpm restart
Configure Symfony for Redis Sessions
Now you must configure some things in Symfony. Part of the following can be found in the docs about caching in a Redis Database here.
From the docs you can see you need set these values inside services.yaml which is in the config directory of your app.
/yourapp/config/services.yaml services: # ... Redis: # you can also use \RedisArray, \RedisCluster or \Predis\Client classes class: Redis calls: - connect: - '%env(REDIS_HOST)%' - '%env(int:REDIS_PORT)%' # uncomment the following if your Redis server requires a password # - auth: # - '%env(REDIS_PASSWORD)%' Symfony\Component\HttpFoundation\Session\Storage\Handler\RedisSessionHandler: arguments: - '@Redis'
Now there is still a little more configuring as the docs show in the link above. You need to configure the framework to use Redis for session storage. Open framework.yaml located in config/packages/ and change the handler_id and comment out the save_path file location info like so.
session: enabled: true handler_id: Symfony\Component\HttpFoundation\Session\Storage\Handler\RedisSessionHandler #save_path: '%kernel.project_dir%/var/sessions/%kernel.environment%' cookie_secure: auto cookie_samesite: lax
Configure Symfony Cache to use Redis
You also need to configure the cache now in cache.yaml if you want to use Redis as a cache for your app. You could configure everything in framework.yaml but it becomes a mess if you do that. Symfony reads all the files recursively located in the config directory, just make sure your yaml structure is correct.
If you open /yourapp/config/packages/cache.yaml you should see something similar already there.
/yourapp/config/packages/cache.yaml framework: cache: # Unique name of your app: used to compute stable namespaces for cache keys. prefix_seed: sogizmo # The "app" cache stores to the filesystem by default. # The data in this cache should persist between deploys. # Other options include: # Redis app: cache.adapter.redis default_redis_provider: 'redis://%env(REDIS_HOST)%:%env(REDIS_PORT)%' #default_redis_provider: redis://localhost:6379 # APCu (not recommended with heavy random-write workloads as memory fragmentation can cause perf issues) #app: cache.adapter.apcu # Namespaced pools use the above "app" backend by default #pools: #my.dedicated.cache: null
Un-comment the lines shown under Redis section. You will notice a special syntax I am using. I kept messing around until it worked. You might not need to configure the default_redis_provider I need to do more research on that because it seems like that should be covered from the configs above, seems redundant.
That builds the string needed for the configuration basically this ‘redis://localhost:6379’ More about caching here in this Symfonycast. that entire symfony cast is a great explanation of how the environmental system and cache works. More info about the string to connect to a redis provider here in the docs.
Using Symfony Cache in Controllers
This is actually the easy part, but instead of explaining it here I’ll write another article and link to it here, this article is too long already.
Configuring symfony – link to the docs about configuring symfony .env file etc.
Symfony docs store sessions in a database -> includes Redis example
CacheInterface Symfony docs about caching items you need ItemInterface when you want to set an expires time for an item.
PSR6 CacheItemInterface documentation explaining this cache interface which Syfony ItemInterface uses.
Redis cache adapter docs – the documentation about configuring the redis cache adapter.