2

I'm using docker tool belt on windows home edition. I'm trying to use Node with Redis using docker-compose, it is working well when I'm running the image using docker-compose up (in the same source directory), but when I try to run it using docker run -it myusername/myimage, my Node app is not isn't able to connect to Redis.

throwing:

Error: Redis connection to redis-server:6379 failed - getaddrinfo ENOTFOUND redis-server
    at GetAddrInfoReqWrap.onlookup [as oncomplete] (dns.js:60:26) {
  errno: 'ENOTFOUND',
  code: 'ENOTFOUND',
  syscall: 'getaddrinfo',
  hostname: 'redis-server'
}

which I believe is because my node app is not able to find Redis, also even though the app is running when I use docker-compose up, i'm not able to access it on the respective port, i.e. localhost:3000.

this is my docker-compose.yml

version: '3'
services:
  my_api:
    build: .  
    ports:
     - "3000:3000"
    image: my_username/myimage
    links: 
     - redis-server:redis-server 
  redis-server:
    image: "redis:alpine"

there are two issues i'm facing and I believe both of them are interrelated.

EDIT

could this be because of virtualization issue of windows home edition? because it doesn't uses Hyper V, I've just try my hands on docker so I don't know about it much, but David's answer makes much sense that it maybe because of various networks and I need to connect to the valid bridge or so.

here is what I get when I do docker network ls

NETWORK ID          NAME                      DRIVER              SCOPE
5802daa117b1        bridge                    bridge              local
7329d018df1b        collect_api_mod_default   bridge              local
5491bfee5551        host                      host                local
be1353789426        none                      null                local
9
  • what do you mean by other direcotry? if you restart the redis you must restart the my_api too otherwise my_api will throw connection refused. BTW do not use linking. docker-compose create network for you. just refer the container name Commented Sep 20, 2019 at 12:17
  • @Adiii when I do docker-compose up it runs my local image, but when I do docker run my_image it doesn't run, it gives the error above, different directory means that of course I can't do docker-compose up from another directory than the source. Commented Sep 20, 2019 at 14:08
  • Did you add link in your docker run Commented Sep 20, 2019 at 14:32
  • You should not only, you should allocate tty with it Commented Sep 20, 2019 at 14:32
  • @Adii ya as I did, docker run myusername/myimage, I didn't add the -it flag, sorry for basic mistakes I'm just trying out docker, I'll try it when I'm back home. Commented Sep 20, 2019 at 14:56

3 Answers 3

3

When you run the whole stack in the same docker-compose.yml file, Compose automatically creates a Docker network for you, and this makes cross-service DNS requests work.

If you are trying to manually docker run a container, and you don't specify a --net option at all, you get a thing Docker calls the default bridge network, which is distinctly less useful. You need to make sure your container is attached to the same Docker-internal network as the Redis server.

You can run docker network ls to get a listing of Docker networks; given that docker-compose.yml file there will probably be one named something like source_directory_default. Take that name and pass it to your docker run command (before the image name)

docker run --net source_directory_default -p 3000:3000 my_username/my_api
Sign up to request clarification or add additional context in comments.

1 Comment

the docker network ls command listed three network ids, I tried three of them but it didn't work, I the problem maybe related to the networking, because I'm using Windows home edition, it uses virtualization. also I later checked that I'm not able to connect to the app running in the container.
1

working index.js for lates version of node and lates version of redis, both working with docker, hope it helps

const express = require('express');
const redis = require('redis');

const app = express()
const client = redis.createClient({
    url: 'redis://redis-server', // redis:// + docker-compose service name
    port: 6379 // redis default port
});
client.connect()
client.on('error', (err) => console.log('Redis Client Error', err));
client.on('connect', async () => {
    await client.set('visits', 0)
    console.log('Redis Client Connected');
});




app.get('/', async (req, res) => {
    const value = await client.get('visits');
    await client.set('visits', parseInt(value) + 1);
    res.send('Number of visits: ' + value);
});

app.listen(8081, () => {
    console.log('Listening on port 8080')
})

Comments

0

So, after a lot of searching for answers, I found out was the solution was mentioning your container-name as your redis url, in index.js file.

const client = redis.createClient({
    url: 'redis://container-name',
    port: 6379 // redis default port
});

One best way to do this without changing your code (i.e. in DevOps manner) is by providing an ENV variable and then setting that ENV variable in your docker compose file.

const client = redis.createClient(process.env.REDIS_URL)
version: '3'

services:
  my_api:
    build: .  
    ports:
     - "3000:3000"
    image: my_username/myimage
    depends_on:
        - redis-server
    environment:
        - REDIS_URL=redis://redis-host
  redis-server:
    image: "redis:alpine"
    container-name: redis-host

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.