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.
CodePudding user response:
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
CodePudding user response:
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();
}
}