Laravel/docker-compose/redis - Class 'Redis' not found - php

This project was set up by another team and I'm unable to get passed this one error. Using PHP 7.2 and Laravel 6.2. My docker-compose.yml:
redis:
image: redis
command: ["redis-server", "--appendonly", "yes","--requirepass","Redis.123"]
volumes:
- redis-data:/data
container_name: redis-master
ports:
- "6379:6379"
and database.php:
'redis' => [
'client' => env('REDIS_CLIENT', 'phpredis'),
'options' => [
'cluster' => env('REDIS_CLUSTER', 'redis'),
'prefix' => env('REDIS_PREFIX', Str::slug(env('APP_NAME', 'laravel'), '_').'_database_'),
],
'default' => [
'url' => env('REDIS_URL'),
'host' => env('REDIS_HOST', '127.0.0.1'),
'password' => env('REDIS_PASSWORD', null),
'port' => env('REDIS_PORT', 6379),
'database' => env('REDIS_DB', 0),
],
'cache' => [
'url' => env('REDIS_URL'),
'host' => env('REDIS_HOST', '127.0.0.1'),
'password' => env('REDIS_PASSWORD', null),
'port' => env('REDIS_PORT', 6379),
'database' => env('REDIS_CACHE_DB', 1),
],
]
The container is up and running and "Ready to accept connections". This error is in my stack trace if I attempt to hit the base url or any endpoints. I have aliased redis in app.php: 'RedisManager' => Illuminate\Support\Facades\Redis::class, as others have recommended. Can anyone see anything obvious that is missing or could cause this? Predis is installed in the composer.json: "predis/predis": "^1.1",, but not set in the config. If I changed phpredis to predis I get the error development.ERROR:SELECTfailed: NOAUTH Authentication required. [tcp://127.0.0.1:6379].

The error you get when you set to phpredis, it is most likely related to phpredis extension. You need to install this extension if you want to use phpredis client.
The error you get when you set it to predis is totally different. It is authentication error because you didn't set password. In your .env file, append this
REDIS_PASSWORD=Redis.123
Then artisan config:clear, it could do the work.

In .end file, please put REDIS_HOST=redis-master which is your redis container name.

Related

Laravel 8 & Redis - Predis\Connection\ConnectionException Connection timed out

I'm trying to connect Laravel application to Redis (hosted by DigitalOcean) but without success. I'm getting the following error:
Predis\Connection\ConnectionException
Connection timed out [tls://private-db-redis-ams3-xxxxyyyyzzzz.db.ondigitalocean.com:25061]
Here is how my .env file's looking:
REDIS_HOST=db-redis-ams3-xxxxyyyyzzzz.db.ondigitalocean.com
REDIS_PASSWORD=alfjaslkdfjwlkfjlweh
REDIS_PORT=25061
And here's config/database.php
'redis' => [
'client' => env('REDIS_CLIENT', 'predis'),
'options' => [
'cluster' => env('REDIS_CLUSTER', 'redis'),
'prefix' => env('REDIS_PREFIX', Str::slug(env('APP_NAME', 'laravel'), '_').'_database_'),
],
'default' => [
'scheme' => 'tls',
'url' => env('REDIS_URL'),
'host' => env('REDIS_HOST', '127.0.0.1'),
'password' => env('REDIS_PASSWORD', null),
'port' => env('REDIS_PORT', '6379'),
'database' => env('REDIS_DB', '0'),
],
'cache' => [
'url' => env('REDIS_URL'),
'host' => env('REDIS_HOST', '127.0.0.1'),
'password' => env('REDIS_PASSWORD', null),
'port' => env('REDIS_PORT', '6379'),
'database' => env('REDIS_CACHE_DB', '1'),
],
],
I added the IP of the web server inside the Trusted Sources section in DigitalOcean's Redis Server Control Panel but it still doesn't want to connect. I tried almost every solution from Google searches. I'm stuck, every help is greatly appreciated!

Connection refused [tcp://127.0.0.1:6379] Laravel Predis

I'm trying to setup Redis client to connect to the Redis server in Laravel 6.0 version, but when I try to change the REDIS_HOST in database.php file in config it gives me an error:
Connection refused 127.0.0.1:6379
This is how my code looks like in routes api.php file
Route::get('test',function(Request $request){
$redis=Redis::connection();
$redis->set("key1","keyValue");
$a=$redis->get("key1");
return response()->json( ['test'=>$a,]);
});
and this is how my database.php file looks like
'redis' => [
'client' => env('REDIS_CLIENT', 'predis'),
'options' => [
'cluster' => env('REDIS_CLUSTER', 'redis'),
'prefix' => env('REDIS_PREFIX', Str::slug(env('APP_NAME', 'laravel'), '_').'_database_'),
],
'default' => [
'url' => env('REDIS_URL'),
'host' => env('REDIS_HOST', '127.0.0.1'),
'password' => env('REDIS_PASSWORD', null),
'port' => env('REDIS_PORT', 6379),
'database' => env('REDIS_DB', 0),
],
'cache' => [
'url' => env('REDIS_URL'),
'host' => env('REDIS_HOST', '127.0.0.1'),
'password' => env('REDIS_PASSWORD', null),
'port' => env('REDIS_PORT', 6379),
'database' => env('REDIS_CACHE_DB', 1),
],
],
So when i change the REDIS_HOST its gives me error,any idea is my code problem the configurations?
Thanks !
I encountered this on my MacBook and fixed it by installing Redis using homebrew as directed here
PS: I'm working with Laravel 8.40

Conflict database when Multiple Laravel Projects on single machine or laravel not reading .env file

I am using xampp on windows 10. I have multiple laravel 5.2 projects on this machine. When I am executing Project 1 it gives me the error that database_project_1.table_of_project_2 table or view do not exist, but the table table_of_project_2 is existing in the database_project_2. This issue comes rarely.
Below is the Project 1 .env file
APP_ENV=local
APP_DEBUG=true
APP_KEY=base64:ratSluNv930gb3wp1UOabW6Ze3jEJn3ixtTX/wgqYZc=
APP_URL=http://project-1.dev/
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=database_project_1
DB_USERNAME=root
DB_PASSWORD=j#yshr33r#m
Below is the Project 2 .env file
APP_ENV=local
APP_DEBUG=true
APP_KEY=base64:XRgQHfYiKPmHtHZ5UbX38KDlBnl/nyBSt+8qnkOISTg=
APP_URL=http://project-2.dev/
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=database_project_2
DB_USERNAME=root
DB_PASSWORD=j#yshr33r#m
I have tried below commands but with no luck:
php artisan config:clear
php artisan cache:clear
Please check the screenshot below:
Please let me know if any thing is missing.
Here is the config/database.php code for both projects.
Project 1 config/database.php
<?php
return [
'fetch' => PDO::FETCH_CLASS,
'default' => env('DB_CONNECTION', 'mysql'),
'connections' => [
'mysql' => [
'driver' => 'mysql',
'host' => env('DB_HOST', 'localhost'),
'port' => env('DB_PORT', '3306'),
'database' => env('DB_DATABASE', 'database_project_1'),
'username' => env('DB_USERNAME', 'root'),
'password' => env('DB_PASSWORD', 'j#yshr33r#m'),
'charset' => 'utf8',
'collation' => 'utf8_unicode_ci',
'prefix' => '',
'strict' => false,
'engine' => null,
],
],
'migrations' => 'migrations',
'redis' => [
'cluster' => false,
'default' => [
'host' => env('REDIS_HOST', 'localhost'),
'password' => env('REDIS_PASSWORD', null),
'port' => env('REDIS_PORT', 6379),
'database' => 0,
],
],
];
Project 2 config/database.php
<?php
return [
'fetch' => PDO::FETCH_CLASS,
'default' => env('DB_CONNECTION', 'mysql'),
'connections' => [
'mysql' => [
'driver' => 'mysql',
'host' => env('DB_HOST', 'localhost'),
'port' => env('DB_PORT', '3306'),
'database' => env('DB_DATABASE', 'database_project_2'),
'username' => env('DB_USERNAME', 'root'),
'password' => env('DB_PASSWORD', 'j#yshr33r#m'),
'charset' => 'utf8',
'collation' => 'utf8_unicode_ci',
'prefix' => '',
'strict' => false,
'engine' => null,
],
],
'migrations' => 'migrations',
'redis' => [
'cluster' => false,
'default' => [
'host' => env('REDIS_HOST', 'localhost'),
'password' => env('REDIS_PASSWORD', null),
'port' => env('REDIS_PORT', 6379),
'database' => 0,
],
],
];
Take a look at the code and let me know anything required.
Is it problem with reading .env file or conflicting .envfile of another project?
You have specified to use database_project_1 in Project 2's config/database.php:
'database' => env('DB_DATABASE', 'database_project_1'),
So if ever env('DB_DATABASE') does not return a value , the default of database_project_1 will be used. That can happen depending on caching, as described in a few questions here on SO: example 1, example 2, example 3.
If it is a caching issue, you can try to fix that by some combination of the following (varies between installs and versions):
php artisan config:clear
php artisan cache:clear
composer dump-autoload
// restart your web server
But surely the simplest fix would be to just use the correct default value in your Project 2 config/database.php:
'database' => env('DB_DATABASE', 'database_project_2'),
On production we should use cache for config and should not use env('xxx') at runtime.
If you like to use env function, I suggest that use different name for each project
DB_DATABASE_PROJECT1=pro1
DB_USERNAME_PROJECT1=user1
DB_PASSWORD_PROJECT1=xxx
and
'database' => env('DB_DATABASE_PROJECT1', 'project_1'),
...
cache
php artisan cache:clear
php artisan view:clear
php artisan route:clear
php artisan clear-compiled
php artisan config:cache
php artisan route:cache

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 :)
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:
'client' => 'predis': This specifies the PHP Library Redis driver to use (predis).
'cluster' => 'redis': This tells Predis to assume server-side clustering. Which just means "follow redirects" (e.g. -MOVED responses). When running with a cluster, a node will respond with a -MOVED to the node that you must ask for a specific key.
If you don't have this enabled with Redis Clusters, Laravel will throw a -MOVED exception 1/n times, n being the number of nodes in Redis cluster (it'll get lucky and ask the right node every once in awhile)
'clusters' => [...] : Specifies a list of nodes, but setting just a 'default' and pointing it to the AWS 'Configuration endpoint' will let it find any/all other nodes dynamically (recommended for Elasticache, because you don't know when nodes are comin' or goin').
'options': For Laravel, can be specified at the top-level, cluster-level, and node option. (they get combined in Illuminate before being passed off to Predis)
'parameters': These 'override' the default connection settings/assumptions that Predis uses for new connections. Since we set them explicitly for the 'default' connection, these aren't used. But for a cluster setup, they are critical. A 'master' node may send back a redirect (-MOVED) and unless the parameters are set for password and scheme it'll assume defaults, and that new connection to the new node will fail.
Thank you CenterOrbit!!
I can confirm the first solution does allow Laravel to connect to a Redis server over TLS. Tested with Redis 3.2.6 on AWS ElastiCache with TLS, configured as single node and single shard.
I can also confirm the second solution does allow Laravel to connect to a Redis Cluster over TLS. Tested with Redis 3.2.6 on AWS ElastiCache with TLS, configured with "Cluster Mode Enabled", 1 shard, 1 replica per shard.
I was receiving the following error when I first tried to implement the cluster solution:
Error: Unsupported operand types
I missed the additional set of array brackets when I moved the "default" settings into the "clusters" array.
INCORRECT
'clusters' => [
'default' => [
'scheme' ...
]
]
CORRECT
'clusters' => [
'default' => [
[
'scheme' ...
]
]
]
I hope this saves someone else a bit of troubleshooting time.
The accepted solution by CenterOrbit worked for me, as I was using AWS I had to add tls:// in my .env
Laravel
tls://username:password#URL:PORT?database=0
Try it. It will work

Laravel: how to separate cache and session into different redis database?

I want to put session and cache data into redis. This is my configuration in database.php:
'redis' => array(
'cluster' => false,
'default' => array(
'host' => '192.168.56.101',
'port' => 6379,
'database' => 0,
),
'session' => array(
'host' => '192.168.56.101',
'port' => 6379,
'database' => 1,
),
),
session.php:
return array(
'driver' => 'redis',
'connection' => 'session',
);
cache.php:
'driver' => 'redis',
However, where I write code like this:
Cache::remember('aa',1,function(){
return 'bb';
});
cache driver uses the same redis database as session driver does, which results in:
127.0.0.1:6379[1]> keys *
1) "aa"
2) "e0606244bec40b0352fb2b7b65d98049e49f6189"
Anyone knows how to force cache to use a specific redis connection? Or I have to mix them up together?
Introduction
Here is my note, for some other guy who running in to this problem, I think this is should be in the docs.
By default, redis gives you 16 separate databases, but laravel out of the box will try to use database 0 for both sessions and cache.
Our solution is to let Redis caching using database 0, and database 1 for Session, there for solving the session clear by running php artisan cache:clear problem.
Note: Tested at Laravel 5.1
1. Setting up Session Redis connection
Modify config/database.php, add session key to the redis option:
'redis' => [
'cluster' => false,
'default' => [
'host' => env('REDIS_HOST', 'localhost'),
'password' => env('REDIS_PASSWORD', null),
'port' => env('REDIS_PORT', 6379),
'database' => 0,
],
'session' => [
'host' => env('REDIS_HOST', 'localhost'),
'password' => env('REDIS_PASSWORD', null),
'port' => env('REDIS_PORT', 6379),
'database' => 1,
],
],
2. Make use of the session connection
Modify config/session.php, change the following:
'connection' => null,
to:
'connection' => 'session',
3. Using Redis as session driver
Modify .env, change SESSION_DRIVER:
SESSION_DRIVER=redis
4. Testing out
Execute the following artisan command, then check your login state:
php artisan cache:clear
If the login state persists, voilĂ !
Laravel 5.5:
database.php should look like this:
'redis' => [
'client' => 'predis',
'default' => [
'host' => env('REDIS_HOST', '127.0.0.1'),
'password' => env('REDIS_PASSWORD', null),
'port' => env('REDIS_PORT', 6379),
'database' => 0,
],
'session' => [
'host' => env('REDIS_HOST', '127.0.0.1'),
'password' => env('REDIS_PASSWORD', null),
'port' => env('REDIS_PORT', 6379),
'database' => 1,
],
],
And in the session.php you have to update also the key "connection" to the right key. In this case 'session'
'connection' => 'session',
Laravel 5 now supports this.
https://github.com/laravel/framework/commit/d10a840514d122fa638eb5baa24c8eae4818da3e
You can select redis connection by modifying config/cache.php
'stores' => [
'redis' => [
'driver' => 'redis',
'connection' => 'your-connection-name',
],
],
Laravel 4 CacheManager does not support selecting redis connection.
What you need to do is to modify/extend CacheManager and override createRedisDriver() method.
Modify this line
return $this->repository(new RedisStore($redis, $this->getPrefix()));
To
return $this->repository(
new RedisStore($redis, $this->getPrefix(),
$this->app['config']['cache.redis'])
);
Now you can define your configuration in cache.php
'redis' => 'your-connection-name'

Categories