Elijah Paul
Elijah Paul

Reputation: 281

Single Redis configuration for local and production in Laravel?

I'm trying to set a single Redis configuration in database.php to cover both my local and production (Redis Cluster) environments in Laravel (5.8).

This config works with my local (APP_ENV=local) Redis instance:

'redis' => [

    'client' => 'predis',

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

],

And this works with my production (APP_ENV=production) Redis cluster:

'redis' => [

    'client' => 'predis',

    'options' => [
        'cluster' => 'redis',
    ],

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

],

I want to set a single config so that if APP_ENV=local is set, my local Redis instance is used and setting APP_ENV=production uses my Redis cluster.

I tried the following (with REDIS_CLUSTER set to true) in my APP_ENV=production environment:

'redis' => [

    'client' => 'predis',

    'cluster' => env('REDIS_CLUSTER', false),

    'options' => [
        'cluster' => 'redis',
    ],

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

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

],

but this fails with a MOVED error.

I posted a question on laracasts.com/discuss but that has left me more confused as it seems to suggest that I update my app code (rather than my Redis config in database.php) to accommodate both environments. I feel like I'm missing something obvious here in how the configuration should work.

Upvotes: 1

Views: 1696

Answers (2)

Ringtail
Ringtail

Reputation: 659

Below setup works for me, we only need to set REDIS_HOST =clusterdomain in production, and nothing in development

 $redis = [
        'client' => 'predis',
        'clusters' => [
            'default' => [
                [
                    'host' => env('REDIS_HOST', 'localhost'),
                    'password' => env('REDIS_PASSWORD', null),
                    'port' => env('REDIS_PORT', 6379),
                    'database' => 0,
                ],
            ],
        ],
        'options' => [
            'cluster' => 'redis',
            'prefix' => Str::slug(env('APP_NAME', 'laravel'), '_').'_database_',
        ],
    ];

We are in Laravel 5.6 Debugging in the source code is very helpful. vendor/laravel/framework/src/Illuminate/Redis/RedisManager.php and vendor/predis/predis/src/Client.php

Upvotes: 0

Elijah Paul
Elijah Paul

Reputation: 281

Not sure it's the best (or right) way of achieving this, but I ended up placing the following logic at the top of my database.php file:

<?php

if (env('APP_ENV') == 'production') {
    $redis =  [
        'client' => 'predis',
        'options' => [
            'cluster' => 'redis',
        ],
        'clusters' => [
            'default' => [
                [
                    'host' => env('REDIS_HOST', 'localhost'),
                    'password' => env('REDIS_PASSWORD', null),
                    'port' => env('REDIS_PORT', 6379),
                    'database' => 0,
                ],
            ],
        ],
    ];
}
else {
    $redis = [
        'client' => 'predis',
        'default' => [
            'host' => env('REDIS_HOST', '127.0.0.1'),
            'password' => env('REDIS_PASSWORD', null),
            'port' => env('REDIS_PORT', 6379),
            'database' => 0,
        ],
    ];
}

return [

....

And using the follwoing for my redis key:

    'redis' => $redis

So my production environment uses the Redis cluster configuration and my local uses the local config.

If anyone know of a better way of doing this of why the above

Upvotes: 1

Related Questions