Home > database >  How to connect app container to Redis container with docker compose
How to connect app container to Redis container with docker compose

Time:04-13

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();
  }
}
  • Related