2

I have an express API running in a node container and a redis container. When attempting to connect the node container to redis I am greeted with the following error.

api_1    | events.js:291
api_1    |       throw er; // Unhandled 'error' event
api_1    |       ^
api_1    |
api_1    | Error: Redis connection to localhost:6379 failed - connect ECONNREFUSED 127.0.0.1:6379
api_1    |     at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1144:16)
api_1    | Emitted 'error' event on RedisAdapter instance at:
api_1    |     at RedisClient.onError (/usr/src/api/node_modules/socket.io-redis/dist/index.js:65:22)
api_1    |     at RedisClient.emit (events.js:314:20)
api_1    |     at RedisClient.on_error (/usr/src/api/node_modules/redis/index.js:342:14)
api_1    |     at Socket.<anonymous> (/usr/src/api/node_modules/redis/index.js:223:14)
api_1    |     at Socket.emit (events.js:314:20)
api_1    |     at emitErrorNT (internal/streams/destroy.js:92:8)
api_1    |     at emitErrorAndCloseNT (internal/streams/destroy.js:60:3)
api_1    |     at processTicksAndRejections (internal/process/task_queues.js:84:21) {
api_1    |   errno: 'ECONNREFUSED',
api_1    |   code: 'ECONNREFUSED',
api_1    |   syscall: 'connect',
api_1    |   address: '127.0.0.1',
api_1    |   port: 6379
api_1    | }

Here the code that is establishing the connection:

const redisClient = require("redis").createClient({host: process.env.REDIS_HOST ? process.env.REDIS_HOST : 'localhost'});

I have tried changing 'localhost' to "redis" to "redis://redis:6379". Nothing works.

As I understand it "localhost" in the context of a container refers to its own internal network, however both nodejs and redis are running on the same network which I've specified in my docker compose file.

Docker compose snippet

    api: 
        build: ./api
        ports: 
            - "3004:3004"
        volumes:
            - type: bind
              source: ./api
              target: /usr/src/api
        working_dir: /usr/src/api
        depends_on: 
            - redis
        networks:
            - backend

    redis: 
        image: "redis:latest"
        ports: 
            - "6379:6379"
        hostname: redis
        networks:
            - backend
    ```

What could this be. All the "solutions" that I've managed to find through research don't work for me.
Lorza
  • 459
  • 8
  • 23
  • 2
    `localhost` inside your api container refers to the container itself, not your development/running host. Redis server is not running inside it, but in another container`. So it will never connect using `localhost`. You need to use the redis container name in the url connection. Using `redis` should be OK, but it is not working for you. I believe there might be something not working when passing environmental variables. and they are resolved property, always failing to `localhost`. I cannot see in your compose file any env stuff. How are you initializing them? – usuario Sep 01 '21 at 15:05
  • Sorry the code is misleading. There are no env variables set for REDIS_HOST. So it intentionally falls back to localhost. This is what appears if put redis as the host: https://prnt.sc/1qym8kv – Lorza Sep 01 '21 at 15:09
  • wait I fixed it. Putting redis did work. I assumed that because there was no value for REDIS_HOST it would fall back to what I put in the ternary operator else clause. That fixed the issue. – Lorza Sep 01 '21 at 15:11

1 Answers1

1

Just to close the question, when trying to connect to localhost inside the container it assumes the container itself and because the node.js container doesnt publish on the redis port the connection is refused. On the other hand because using docker-compose, you get a default docker network binding them together so using the container\service names as internal secured DNS records works.

for a more detailed explenation of the docker networking inner works see this thread

Noam Yizraeli
  • 4,446
  • 18
  • 35