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