0

I was looking at this post which seemed to be the exact problem I was facing. I am running a Node/express/mysql/redis based app. I am somewhat familiar with the oddity of how docker bridge network works and had coded my host for both mysql and redis correctly (the exact same thing as what the solution suggested). mysql connects perfectly however redis fails to connect when running as docker containers - but BOTH work perfectly when running outside docker ie node myservice.

Basically When I run my express server via node myservice and connect both BOTH mysql and redis from node it works perfectly. When I deploy and run the app using docker-compose, though I'm able to connect to mysql, it fails while connecting to redis. I checked the docker network ls and inspected the bridge and it has all three apps on the same bridge (kinda makes sense since mysql is connecting just fine). I am printing the bridge names in the code below to make sure i am not using localhost instead (which is how i fixed mysql connection when i started using it locally vs docker)

Bottom line : NodeJS connects correctly to BOTH mysql and redis when running node locally. It connects to mysql but NOT redis when running in docker.

Any thoughts?

Docker Compose

version: '3'
services:
    express-app:
        build:
            context: .
        ports:
            - 3000:3000
        depends_on:
            - redis-db
            - mysql-db
        environment:
            - MYSQL_HOST=mysql-db
            - REDIS_HOST=redis-db

    mysql-db:
        image: mysql:latest
        environment:
            MYSQL_DATABASE: twitter
            MYSQL_USER: user
            MYSQL_PASSWORD: user-password
            MYSQL_ROOT_PASSWORD: root-password
        ports:
            - '3306:3306'
        volumes:
            - my-twitter-db-mount:/var/lib/mysql

    redis-db:
        image: redis
        ports:
            - '6379:6379'
        volumes:
            - my-twitter-redis-mount:/var/lib/redis/data

volumes:
    my-twitter-db-mount:
    my-twitter-redis-mount:

NodeJS Code

const mysql = require('mysql2');
const redis = require('redis');

var connection;
var redisConnection;
const getConnection = (() => {
    console.log("################ "+process.env.MYSQL_HOST) ;
    console.log("################ "+process.env.REDIS_HOST) ;
    
    connection = mysql.createConnection({
        host: process.env.MYSQL_HOST || 'localhost',
        port: 3306,
        user: 'user',
        password: 'user-password'
    });
    
    redisConnection = redis.createClient({
        port: 6379,
        host: process.env.REDIS_HOST || 'localhost'
    });
    
    connection.connect();
    redisConnection.connect();
});

const queryFollowers = (async (ownerId) => {
    getConnection();
    let val = await redisConnection.get(`OwnerCache_${ownerId}`);
    if (val) {
        console.log("Returning the cached value "+val);
        return new Promise((resolve, reject)  => resolve(val));
    }
    console.log("No Cached value found for "+val+ " Querying database...");
    return new Promise((resolve, reject) => { 
        connection.query(`SELECT * from twitter.Users where id IN  (SELECT follower_id from twitter.User_Follower  WHERE user_id = ${ownerId})`, (err, rows, fields) => {
            if (err) reject(err);
            console.log("ROWS "+rows);
            let followers = [];
            if(rows.length > 0)  {
                rows.forEach(user => {
                    followers.push(user);
                });
                redisConnection.set(`OwnerCache_${ownerId}`, JSON.stringify(followers));
                redisConnection.expire(`OwnerCache_${ownerId}`, 10);
                resolve(followers);
            }
        });
    });
});

Error

Its connecting to mysql correctly since I'm using the bridge network name mysql-db. But not redis even though I'm using the bridge network name redis-db. (Like I said, Node connects to BOTH if I'm running this code from outside docker as its defaulting to localhost).

Listening on port 3000
Returning all the followers for ownerID 1
################ mysql-db
################ redis-db
node:internal/process/promises:288
            triggerUncaughtException(err, true /* fromPromise */);
            ^
Error: connect ECONNREFUSED 127.0.0.1:6379
    at TCPConnectWrap.afterConnect [as oncomplete] (node:net:1246:16)
Emitted 'error' event on Commander instance at:
    at RedisSocket.<anonymous> (/app/node_modules/@node-redis/client/dist/lib/client/index.js:339:14)
    at RedisSocket.emit (node:events:513:28)
    at RedisSocket._RedisSocket_connect (/app/node_modules/@node-redis/client/dist/lib/client/socket.js:117:14)
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
    at async Commander.connect (/app/node_modules/@node-redis/client/dist/lib/client/index.js:162:9) {
  errno: -111,
  code: 'ECONNREFUSED',
  syscall: 'connect',
  address: '127.0.0.1',
  port: 6379
}
Node.js v18.6.0
  • In the `redis.createClient()` call, do you need to put `host:` and `port:` inside a `socket: { ... }` block? For example, [this answer](https://stackoverflow.com/a/72135747) to [Docker Redis Error: connect ECONNREFUSED 127.0.0.1:6379](https://stackoverflow.com/questions/71360779/docker-redis-error-connect-econnrefused-127-0-0-16379). – David Maze Jul 16 '22 at 23:43
  • @DavidMaze THAT DID IT!! I would NEVER have figured that out. I trawled through so many SO posts and google (literally of dozens) and this "workaround" never popped up. Thanks much. Power to SO. How does one even solve these problems if such posts are not given such answers? I would be going around in circles. Please add your answer to the main thread so I can mark it as the Answer. – Dorian McAllister Jul 17 '22 at 00:13
  • @DorianMcAllister One reads the docs :) https://github.com/redis/node-redis/blob/master/docs/client-configuration.md – Dave Newton Jul 17 '22 at 19:17

0 Answers0