Home > Enterprise >  Unable to connect to redis docker container with my node docker container
Unable to connect to redis docker container with my node docker container

Time:10-22

This is my first time of using docker and I am trying to 'dockerize' my nodejs application which relies on redis data base as well as mongo atlas database. I have created both containers for nodejs and redis but I can't seem to get them connected. When I start the redis container and start my nodejs application locally outside docker, it runs fine. My nodejs and my redis container are able to communicate. However, making the nodejs a container, I can't seem to connect to the redis database. I am using redis npm version ^4.0.2 and I am using windows 11. Here are my codes so far:

my redis connection:

const redis = require('redis');
let redis_client = redis.createClient()


  redis_client.connect()

  redis_client.on('connect', function(){
  console.log('redis client connected')
  });

Dockerfile

 FROM  node:lts-alpine

 WORKDIR /app

 COPY package*.json ./

 COPY client/package*.json client/
 RUN npm run install-client --only=production

 COPY api/package*.json api/
 RUN npm run install-api --only=production

 COPY client/ client/
 RUN npm run client-build --prefix client

 COPY api/ api/

 USER node

 CMD [ "npm", "start", "--prefix", "api" ]

 EXPOSE 5000

docker-compose file

version: "3"
services:
  redisDB:
    container_name: redisDB
    hostname: redis
    image: redis
    ports:
     - "6379:6379"

  fullstack-cms:
    build: .
    ports:
      - "5000:5000"
    env_file:
      - ./api/.env
    depends_on:
      - redisDB
    links:
      - redisDB

I used this command to build the images: docker-compose up -d --build

However, I get error:

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

How do I fix this error?

CodePudding user response:

There are several aspects of your compose configuration that aren't necessary, and a couple that may be causing problems:

  • As I mentioned in the comment, links is deprecated. When you create an environment using docker-compose (or more generally, whenever you attach containers to a user-defined network), Docker maintains a DNS service that allows your containers to refer to each other by name.

  • You don't need to set either the container_name or hostname for your services in most cases.

  • You may not need to publish ports for your redis container. If it's just acting as a backend for the fullstack-cms service then the ports section isn't necessary. That's only important if you intend to connect to redis from your host (or from a remote host).

Applying all those changes, we end up with something like this:

version: "3"

services:
  redisdb:
    image: redis

  fullstack-cms:
    build: .
    env_file:
      - ./app/.env
    ports:
      - "8000:8000"

(And you can drop the env_file directive if you rename app/.env to .env, because docker-compose will load that automatically.)

I'm not a competent Node.js developer, so I've written an example Python application that works correctly with the above configuration. You can find a complete, runnable example here if you're so inclined.

Looking at that code, you can see that there is logic around the initial database connection that will retry it until the connection is successful:

while True:
    try:
        db = redis.Redis(host="redisdb", port=6379, db=0)
        db.set("color", "blue")
    # A connection could fail because either (a) the hostname doesn't exist
    # yet (that's the socket.gaierror exception) or (b) if the hostname
    # resolves but we're unable to connecto redis (that's the 
    # redis.exceptions.ConnectionError exception).
    except (redis.exceptions.ConnectionError, socket.gaierror):
        print('waiting for redis', file=sys.stderr)
        time.sleep(1)
    else:
        break

You may want to implement something similar in your node.js code. You can test if it's a timing problem by bringing up the services separately. First bring up redis:

docker-compose up -d redisdb

Wait a minute, then bring up the frontend:

docker-compose up fullstack-cms

If this works, but a simple docker-compose up fails, it's probably a timing issue.

CodePudding user response:

I solved the problem with this code:

let redis_client = redis.createClient({
url: 'redis://redis:6379',
legacyMode: true,
 })

Thanks for the first comment for a headup.

  • Related