9
votes

I can't figure out how to connect to my redis service from my app service. Using DDocker version 18.03.1-ce, build 9ee9f40ocker for Mac.

I've tried connecting the various ways I've found on similar questions:

const client = redis.createClient({ host: 'localhost', port: 6379});

const client = redis.createClient({ host: 'redis', port: 6379});

const client = redis.createClient('redis://redis:6379');

const client = redis.createClient('redis', 6379); // and reversed args

I always get some form of:

Error: Redis connection to localhost:6379 failed - connect ECONNREFUSED 127.0.0.1:6379

Error: Redis connection to redis:6379 failed - connect ECONNREFUSED 172.20.0.2:6379

Docker containers

$ docker ps
CONTAINER ID        IMAGE                COMMAND                  CREATED              STATUS              PORTS                    NAMES
0fd798d58561        app_app         "pm2-runtime start e…"   2 seconds ago        Up 7 seconds                                 app
65d148e498f7        app_redis       "docker-entrypoint.s…"   About a minute ago   Up 8 seconds        0.0.0.0:6379->6379/tcp   redis

Redis works:

$ docker exec -it redis /bin/bash
root@65d148e498f7:/data# redis-cli ping
PONG

Redis Dockerfile (pretty simple)

FROM redis:4.0.9
COPY redis.conf /usr/local/etc/redis/redis.conf
CMD ["redis-server", "/usr/local/etc/redis/redis.conf"]

app Dockerfile

FROM node:10.3.0-slim
RUN mkdir -p /app
COPY src/* /app/
CMD ["pm2-runtime", "start", "/app/ecosystem.config.js"]

docker-compose.yml

version: "3"
services:
  redis:
    build: ./redis/
    container_name: redis
    restart: unless-stopped
    ports:
      - "6379:6379"
    expose:
      - "6379"
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
    environment:
      - 'API_PORT=6379'
      - 'NODE_ENV=production'
  app:
    depends_on:
      - redis
    build: ./app/
    container_name: app
    restart: unless-stopped
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - /app/node_modules
    environment:
      - 'NODE_ENV=production'
5
Check your host 6379 port. Is anythings used that port ? sudo lsof -i tcp:6379 - Truong Dang
@TruongDang it shows no output. I originally used a different port but switched back to 6379 to debug. Both had the same error as noted above. - d-_-b
Can you build your image and try replace build: ./redis/ to image: your_image_name_build_from_dockerfile ? - Truong Dang
Seem your Redis not yet start... May you need to check your docker file, and redis configuration... - Truong Dang
Please include the error message that doesn't show it connecting to localhost or 127.0.0.1 since that won't work between containers. - BMitch

5 Answers

5
votes

It looks like your redis image is configured to listen on 127.0.0.1 rather than all interfaces. This is not an issue with the default redis images, so either use the official image from docker hub, or correct your configuration to listen on 0.0.0.0.

You'll be able to verify this with netshoot:

docker run --rm --net container:app_redis nicolaka/netshoot netstat -ltn

In the redis conf, listening on all interface is done by commenting out the "bind" line in redis.conf.

4
votes

Let me explain it in simple language. When you run docker-compose up it runs redis and app in separate containers. Now your app needs to connect/access the redis container (remember redis is not at your machines localhost, its inside a container and runs inside it at default port 6379). By default Docker will keep app container and redis container in same network and you can access a container by its service name (which in your case is redis and app) so in order to access redis from app container all you need is to use the default port 6379 and host will be the service name (in your case "redis").

For a node application running in a container get access to Redis (which was also running in a container) by

const redis = require("redis");
const client = redis.createClient(6379, "service-name-for-redis-container");
1
votes

I solve this problem changing the redis host from 'localhost' to 'redis', exemple:

REDIS_HOST=redis

REDIS_PORT=6379

After the change my docker service started to comunicate with redis.

Original forum answer: https://forums.docker.com/t/connecting-redis-from-my-network-in-docker-net-core-application/92405

1
votes

In my case the problem was that I was binding a different port on redis:

redis:
    image: redis
    ports:
        - 49155:6379

And I was trying to connect to port 49155 but I needed to connect through port 6379 since the connection is from another service.

0
votes

localhost from the app container's perspective won't be able to leave the app container. So the best bet is to use redis or the host's ip address.

If you want to reach redis from the app container, you'll need to link them or put them into the same network. Please add a network property to both services, using the same network name. Docker will then provide you with with valid dns lookups for the service names.

See the official docs at https://docs.docker.com/compose/compose-file/#networks (for the service: property) and https://docs.docker.com/compose/compose-file/#network-configuration-reference (for the top-level networks property).