Search code examples
node.jsdockerdocker-composerediscontainers

nodejs container won't connect to redis container docker-compose


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.

Solution

  • 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