3

I am trying to set up two socket.io nodejs servers and both are connected to Redis for communication between them, all inside Docker.

I keep getting error I think it's related to:

const { createClient } = require("redis");
const { createAdapter } = require("@socket.io/redis-adapter");

const pubClient = createClient({ host: "redis", port: 6379 }); // <- this host
const subClient = pubClient.duplicate();

I tried many solutions none worked for me, I am new to docker.

My files:

Dockerfile:

FROM node:16.8
WORKDIR /home/node/app
COPY app /home/node/app/
RUN npm install
CMD npm run app 
EXPOSE 9999 6379

index.js:

const express = require("express");
const app = express();
const server = require("http").createServer(app);
const bodyParser = require("body-parser");
const appid = process.env.APPID;

app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
const cors = require("cors");
app.use(cors());
app.use(express.json({ limit: "8mb" }));


const { createClient } = require("redis");
const { createAdapter } = require("@socket.io/redis-adapter");

const pubClient = createClient({ host: "redis", port: 6379 });
const subClient = pubClient.duplicate();

const io = require("socket.io")(server, {
  cors: {
    origin: "*",
    methods: ["GET", "POST"],
  },
});

Promise.all([pubClient.connect(), subClient.connect()]).then(() => {
  io.adapter(createAdapter(pubClient, subClient));
});

var allUsers = {};

app.get("/", async (req, res) => {
  res.send(`Hello from server ${appid}`);
});

io.on("connection", (socket) => {
  console.log("User connected: " + socket.id);
  socket.emit("port", appid);

  socket.on("message", (message) => {
    socket.broadcast.emit("new-message", message);
  });

  socket.on("disconnecting", (socket) => {
    console.log("User disconnected: ", socket.id);
  });
});

server.listen(appid, () => console.log(`Server running on port ${appid}`));

haproxy.cfg:

defaults
  mode http
  timeout client          35s
  timeout connect          5s
  timeout server          35s
  timeout tunnel         120s
  timeout http-keep-alive  1s
  timeout http-request    15s
  timeout queue           30s
  timeout tarpit          60s
  timeout http-request   10s

frontend http
    bind *:8080
    timeout client 10s
    use_backend all

backend all
    server s1 nodeapp1:1111
    server s2 nodeapp2:2222

docker-compose.yml

version : '3'

services:
    redis:
        image: redis
        ports:
            - "6379:6379"
    lb:
        image: haproxy
        ports:
            - "8080:8080"
        volumes:
            - ./haproxy:/usr/local/etc/haproxy
    nodeapp1:
        image: nodeapp
        environment:
            - APPID=1111
        depends_on:
            - redis lb
    nodeapp2:
        image: nodeapp
        environment:
            - APPID=2222
        depends_on:
            - redis lb

This is the error I am getting, I don't really understand it, I did a lot of search on the error code but I didn't find a solution sadly.

docker-redis-1     | 1:M 13 Apr 2022 03:31:07.857 * Ready to accept connections
docker-nodeapp2-1  | 
docker-nodeapp2-1  | > [email protected] app
docker-nodeapp2-1  | > node index.js
docker-nodeapp2-1  |
docker-nodeapp1-1  | 
docker-nodeapp1-1  | > [email protected] app
docker-nodeapp1-1  | > node index.js
docker-nodeapp1-1  |
docker-nodeapp2-1  | Server running on port 2222
docker-nodeapp2-1  | node:internal/process/promises:246
docker-nodeapp2-1  |           triggerUncaughtException(err, true /* fromPromise */);
docker-nodeapp2-1  |           ^
docker-nodeapp2-1  |
docker-nodeapp2-1  | Error: connect ECONNREFUSED 127.0.0.1:6379
docker-nodeapp2-1  |     at TCPConnectWrap.afterConnect [as oncomplete] (node:net:1146:16)
docker-nodeapp2-1  | Emitted 'error' event on Commander instance at:
docker-nodeapp2-1  |     at RedisSocket.<anonymous> (/home/node/app/node_modules/@node-redis/client/dist/lib/client/index.js:339:14)
docker-nodeapp2-1  |     at RedisSocket.emit (node:events:394:28)
docker-nodeapp2-1  |     at RedisSocket._RedisSocket_connect (/home/node/app/node_modules/@node-redis/client/dist/lib/client/socket.js:117:14)
docker-nodeapp2-1  |     at processTicksAndRejections (node:internal/process/task_queues:96:5)       
docker-nodeapp2-1  |     at async Commander.connect (/home/node/app/node_modules/@node-redis/client/dist/lib/client/index.js:162:9)
docker-nodeapp2-1  |     at async Promise.all (index 0) {
docker-nodeapp2-1  |   errno: -111,
docker-nodeapp2-1  |   code: 'ECONNREFUSED',
docker-nodeapp2-1  |   syscall: 'connect',
docker-nodeapp2-1  |   address: '127.0.0.1',
docker-nodeapp2-1  |   port: 6379
docker-nodeapp2-1  | }
docker-nodeapp1-1  | Server running on port 1111
docker-lb-1        | [NOTICE]   (1) : New worker (9) forked
docker-lb-1        | [NOTICE]   (1) : Loading success.
docker-nodeapp1-1  | node:internal/process/promises:246
docker-nodeapp1-1  |           triggerUncaughtException(err, true /* fromPromise */);
docker-nodeapp1-1  |           ^
docker-nodeapp1-1  |
docker-nodeapp1-1  | Error: connect ECONNREFUSED 127.0.0.1:6379
docker-nodeapp1-1  |     at TCPConnectWrap.afterConnect [as oncomplete] (node:net:1146:16)
docker-nodeapp1-1  | Emitted 'error' event on Commander instance at:
docker-nodeapp1-1  |     at RedisSocket.<anonymous> (/home/node/app/node_modules/@node-redis/client/dist/lib/client/index.js:339:14)
docker-nodeapp1-1  |     at RedisSocket.emit (node:events:394:28)
docker-nodeapp1-1  |     at RedisSocket._RedisSocket_connect (/home/node/app/node_modules/@node-redis/client/dist/lib/client/socket.js:117:14)
docker-nodeapp1-1  |     at processTicksAndRejections (node:internal/process/task_queues:96:5)       
docker-nodeapp1-1  |     at async Commander.connect (/home/node/app/node_modules/@node-redis/client/dist/lib/client/index.js:162:9)
docker-nodeapp1-1  |     at async Promise.all (index 0) {
docker-nodeapp1-1  |   errno: -111,
docker-nodeapp1-1  |   code: 'ECONNREFUSED',
docker-nodeapp1-1  |   syscall: 'connect',
docker-nodeapp1-1  |   address: '127.0.0.1',
docker-nodeapp1-1  |   port: 6379
docker-nodeapp1-1  | }
docker-nodeapp2-1 exited with code 1
docker-nodeapp1-1 exited with code 1

I hope someone could help me with this. Thank you in advance.

1
  • The redis host name looks right, but it doesn't seem like it's having an effect; the application container is connecting to 127.0.0.1 instead (localhost, which is to say, the application container itself). Do you have the syntax of the createClient() call correct? Commented Apr 13, 2022 at 10:59

3 Answers 3

1

depends_on get an array of services that current service is depends on

  • you declare "redis lb" as a single service try this :
nodeapp2:
        image: nodeapp
        environment:
            - APPID=2222
        depends_on:
            - redis
            - lb
        restart: always

now you can connect to redis by it's service name as host name in your app code

Sign up to request clarification or add additional context in comments.

2 Comments

I just tried your fix, I still get the same error, ty for your answer tho.
This is syntactically correct, but you don't technically need depends_on: to connect from one container to another.
0

Office Document said https://docs.docker.com/compose/compose-file/compose-file-v3/#depends_on

depends_on does not wait for db and redis to be “ready” before starting web - only until they have been started

The redis container is started but is not ready for connection yet.

Most easy way to do is you can just keep trying until it is ready.

let pubClient;
const pubClient = connectRedis();

function connectRedis() {
  try {
    return createClient({ host: "redis", port: 6379 });
  } catch {
    return connectRedis();
  }
}

1 Comment

Didn't work too :(
0

I faced with same problem. I had configuration similar to you

const pubClient = createClient({ host: "redis", port: 6379 });

I had a remote host, But in logs I saw that pubClient try connect to localhost.

I changed this configuration to

const pubClient = createClient({url: process.env.REDIS_ENDPOINT});

url has format redis://{host}:{port}. More detailed you can see at official site.

And it start to work well.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.