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.
3
Answers
depends_on
get an array of services that current service is depends ontry this :
now you can connect to redis by it’s service name as host name in your app code
Office Document said https://docs.docker.com/compose/compose-file/compose-file-v3/#depends_on
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.
I faced with same problem.
I had configuration similar to you
I had a remote host,
But in logs I saw that pubClient try connect to localhost.
I changed this configuration to
url
has format redis://{host}:{port}. More detailed you can see at official site.And it start to work well.