0

When I run docker container that hass node express app.js it can not connect to redis-stack-server running locally.

However, if I do it without docker container everything works fine.

I ran esbuild to generate one app.js file but it is express ts app. It connects to redis-stack-server. Here is my Dockerfile

FROM node:18

ENV REDIS_URL="redis://localhost:6379"
ENV NODE_PORT=3000

COPY app.js .

EXPOSE 3000
CMD [ "node", "app.js" ]

And here is how I set up redis client in node app:

export const redisC = async () => {
    const client : RedisClientType = createClient();
    client.on('error', (err) => console.error('Redis Client Error', err));
    await client.connect();
    return client;
}

export let redisClient : RedisClientType;
redisC().then((response) => {
    redisClient = response
}).catch(error => console.error(error))

I do run locally:

redis-stack-server

I build docker container:

docker build . -t my-app

Then I run:

docker run -p 3000:3000 my-app

However i face the following issue when I run docker container:

Redis Client Error Error: connect ECONNREFUSED 127.0.0.1:6379
    at TCPConnectWrap.afterConnect [as oncomplete] (node:net:1495:16) {
  errno: -111,
  code: 'ECONNREFUSED',
  syscall: 'connect',
  address: '127.0.0.1',
  port: 6379
}

If I run app.js locally not with docker then everything works.

Express listening on port 3000

And no errors regarding redis connection.

Any help will be very much appreciated. Thanks a lot in advance!

  • Have you tried running “docker run -p 6379:3000 my-app”? Seams like you didn’t change redis default port (in the URL) – A. Guy Aug 10 '23 at 06:43
  • There's a pretty good SO post on how the `localhost` works for inside containers: https://stackoverflow.com/a/24326540/6336357 – Rick Rackow Aug 10 '23 at 07:25
  • @RickRackow that actually helped! Thank you so much. If i change redis client to: const client : RedisClientType = createClient({ url: "redis://host.docker.internal:6379", }); it did the trick! – Gleb Galkin Aug 10 '23 at 13:55

2 Answers2

0

In Docker each container runs in isolation, so localhost means different things. localhost on your machine is not the same as localhost in the express container.

Redis is running on 127.0.0.1:6379 on your machine, but not on that address inside the express container. That's why running express outside of a container works fine.

You probably want Docker compose for this.

services:
  express:
    ...
    environment:
      REDIS_URL: redis:6379
    ports:
      - 3000:3000 // <- forwards traffic from port 3000 on your machine to port 3000 in container

  redis:
    ...
    ports:
      - 6379:6379 // <- same as above

The crucial part is REDIS_URL: redis:6379 in the express service, which tells the express container where redis can be contacted, which in Docker compose is using the service name.

Hoopra
  • 201
  • 2
  • 7
0

[RESOLUTION] This article really helped! To make it work locally we need to change redis URL to:

url: "redis://host.docker.internal:6379"

So my full redis client config:

export const redisC = async () => {
    const client : RedisClientType = createClient({
        url: "redis://host.docker.internal:6379",
    });
    client.on('error', (err) => console.error('Redis Client Error', err));
    await client.connect();
    return client;
}

Thanks a lot everyone for participation! I really much appreciate the help!