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