phplaravelpredis

Laravel + Redis Cache via SSL?


I am trying to connect to Redis with predis 1.1 and SSL, using information https://github.com/nrk/predis, where in the example the following configuration is used:

// Named array of connection parameters:
$client = new Predis\Client([
  'scheme' => 'tls',
  'ssl'    => ['cafile' => 'private.pem', 'verify_peer' => true],
]);

My Laravel configuration looks like below:

'redis' => [
        'client' => 'predis',
        'cluster' => env('REDIS_CLUSTER', false),

        'default' => [
            'host' => env('REDIS_HOST', 'localhost'),
            'password' => env('REDIS_PASSWORD', null),
            'port' => env('REDIS_PORT', 6379),
            'database' => 0,
        ],

        'options' => [
            'cluster' => 'redis',
            'parameters' => ['password' => env('REDIS_PASSWORD', null)],
            'scheme' => 'tls',
        ],
    ],

Unfortunately I am getting the following error:

ConnectionException in AbstractConnection.php line 155:
Error while reading line from the server. [tcp://MY_REDIS_SERVER_URL:6380]

Suggestions are appreciated :)


Solution

  • I was able to get it to work!

    You need to move 'scheme' from 'options' to 'default':

    My working config:

    'redis' => [
        'client' => 'predis',
        'cluster' => env('REDIS_CLUSTER', false),
    
        'default' => [
            'scheme' => 'tls',
            'host' => env('REDIS_HOST', 'localhost'),
            'password' => env('REDIS_PASSWORD', null),
            'port' => env('REDIS_PORT', 6379),
            'database' => 0,
        ],
    
        'options' => [
            'parameters' => ['password' => env('REDIS_PASSWORD', null)],
        ],
    ],
    

    Note: I had also removed the 'cluster' option from 'options', but I don't suspect this to be the make-or-break with this problem.

    In my final-final config, I changed it to: 'scheme' => env('REDIS_SCHEME', 'tcp'), and then defined REDIS_SCHEME=tls in my env file instead.

    Tested with AWS ElastiCache with TLS enabled.

    Edit: The above config only works with single-node redis. If you happen to enable clustering and TLS then you'll need a different config entirely.

    'redis' => [
            'client' => 'predis',
            'cluster' => env('REDIS_CLUSTER', false),
    
            // Note! for single redis nodes, the default is defined here.
            // keeping it here for clusters will actually prevent the cluster config
            // from being used, it'll assume single node only.
            //'default' => [
            //    ...
            //],
    
            // #pro-tip, you can use the Cluster config even for single instances!
            'clusters' => [
                'default' => [
                    [
                        'scheme'   => env('REDIS_SCHEME', 'tcp'),
                        'host'     => env('REDIS_HOST', 'localhost'),
                        'password' => env('REDIS_PASSWORD', null),
                        'port'     => env('REDIS_PORT', 6379),
                        'database' => env('REDIS_DATABASE', 0),
                    ],
                ],
                'options' => [ // Clustering specific options
                    'cluster' => 'redis', // This tells Redis Client lib to follow redirects (from cluster)
                ]
            ],
            'options' => [
                'parameters' => [ // Parameters provide defaults for the Connection Factory
                    'password' => env('REDIS_PASSWORD', null), // Redirects need PW for the other nodes
                    'scheme'   => env('REDIS_SCHEME', 'tcp'),  // Redirects also must match scheme
                ],
            ]
        ]
    

    Explaining the above: