Docker [Errno 111] Connect call failed ('127.0.0.1', 6379)
Asked Answered
R

9

14

I am trying to follow the tutorial here https://channels.readthedocs.io/en/latest/tutorial/part_2.html and check if channel layer can communicate with Redis. The only different thing I'm doing is that I'm using docker-compose and running the entire thing on a docker container, and that seems to be messing up with everything. This is the error message I'm getting when I try to

run async_to_sync(channel_layer.send)('test_channel', {'type': 'hello'})

Traceback (most recent call last):
  File "<console>", line 1, in <module>
  File "/usr/local/lib/python3.7/site-packages/asgiref/sync.py", line 116, in __call__
    return call_result.result()
  File "/usr/local/lib/python3.7/concurrent/futures/_base.py", line 428, in result
    return self.__get_result()
  File "/usr/local/lib/python3.7/concurrent/futures/_base.py", line 384, in __get_result
    raise self._exception
  File "/usr/local/lib/python3.7/site-packages/asgiref/sync.py", line 156, in main_wrap
    result = await self.awaitable(*args, **kwargs)
  File "/usr/local/lib/python3.7/site-packages/channels_redis/core.py", line 293, in send
    async with self.connection(index) as connection:
  File "/usr/local/lib/python3.7/site-packages/channels_redis/core.py", line 820, in __aenter__
    self.conn = await self.pool.pop()
  File "/usr/local/lib/python3.7/site-packages/channels_redis/core.py", line 70, in pop
    conns.append(await aioredis.create_redis(**self.host, loop=loop))
  File "/usr/local/lib/python3.7/site-packages/aioredis/commands/__init__.py", line 175, in create_redis
    loop=loop)
  File "/usr/local/lib/python3.7/site-packages/aioredis/connection.py", line 113, in create_connection
    timeout)
  File "/usr/local/lib/python3.7/asyncio/tasks.py", line 414, in wait_for
    return await fut
  File "/usr/local/lib/python3.7/site-packages/aioredis/stream.py", line 24, in open_connection
    lambda: protocol, host, port, **kwds)
  File "/usr/local/lib/python3.7/asyncio/base_events.py", line 958, in create_connection
    raise exceptions[0]
  File "/usr/local/lib/python3.7/asyncio/base_events.py", line 945, in create_connection
    await self.sock_connect(sock, address)
  File "/usr/local/lib/python3.7/asyncio/selector_events.py", line 473, in sock_connect
    return await fut
  File "/usr/local/lib/python3.7/asyncio/selector_events.py", line 503, in _sock_connect_cb
    raise OSError(err, f'Connect call failed {address}')
ConnectionRefusedError: [Errno 111] Connect call failed ('127.0.0.1', 6379)

I've checked a few post and saw that many suggested this is because Redis isn't running. I know that Redis exist since docker ps shows that

CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                    NAMES
2ccab2cfc570        test_web            "python manage.py ru…"   7 minutes ago       Up 7 minutes        0.0.0.0:8000->8000/tcp   test_web_1
6da398f093fc        redis:2.8           "docker-entrypoint.s…"   10 minutes ago      Up 10 minutes       0.0.0.0:6379->6379/tcp   relaxed_aryabhata

Any idea what I can do right now? I'm really new to these

Rich answered 29/1, 2020 at 22:22 Comment(0)
E
29

Try changing 127.0.0.1:6379 to redis:6379.

Although Redis is running, your python container isn't able to communicate with it; this is because it's trying to connect to 127.0.0.1:6379, but from the container's perspective, there's nothing running there. This can be a bit frustrating to debug, but it's a bit easier if you keep in mind that containers get their own network namespace. As a result, python's localhost != redis's localhost != your host machine's localhost.

Luckily, it's easy to connect containers that are sharing the same bridge, and by default, docker-compose creates a single bridge network and connects all your containers to them, providing the necessary DNS to allow them to discover one another. As a result, container-to-container communication works simply by using the service name.

As a note, it's possible to run containers in the same namespace, and to run in them in the namespace of the host, via the --net=container:<container-id> or --net=host flag. This is especially useful for running debugging tools in a container and attaching them to the network namespace of either another container or the host, e.g. using netshoot to see what ports are listening within the container (exposed or not), docker run --rm -it --net container:test_web_1 nicolaka/netshoot netstat -tulpn.

Ethnic answered 29/1, 2020 at 22:56 Comment(2)
Hi, i have a question, where exactly do I need to change the 127 to redis? As if I change the following: 'CONFIG': { "hosts": [('127.0.0.1', 6379)], }, Then I get socket.gaierror: [Errno -3] Temporary failure in name resolutionIsahella
@Isahella Since you have a DNS failure, you're probably using a different name than that of your service. docker network ls shows the current networks and docker network inspect <name> shows the names of attached containers. For DNS to work the way you expect, both services should be in the same network and refer to each by name. There are other networking details, but this is the common way of handling it with Docker.Ethnic
S
6

Try changing 127.0.0.1:6379 to redis:6379.

it works for me. Just some details

docker-compose.yml

...
  redis:
    image: redis:latest
    ports:
      - "6379:6379"
    volumes:
      - 'redisdata:/data'
....    

CHANNEL_LAYERS = {
    'default': {
        'BACKEND': 'channels_redis.core.RedisChannelLayer',
        'CONFIG': {
            "hosts": [('redis', 6379)],
        },
    },
}
Sesquiplane answered 2/12, 2021 at 15:59 Comment(0)
S
4
docker run -p 6379:6379 -d redis:5

and then start the server

Selfesteem answered 15/7, 2020 at 20:8 Comment(0)
M
3

So I got stuck on this and none of the answers seemed to work for me.

I found that docker would give the container its own IP address. to find the IP address in the command line I used;

'docker ps' to get the container ID. 'docker inspect -f '{{range.NetworkSettings.Networks}}{{.IPAddress}}{{end}} * container-id*' which gave me the IP.

This worked for;

CHANNEL_LAYERS = {
    'default': {
        'BACKEND': 'channels_redis.core.RedisChannelLayer',
        'CONFIG': {
            "hosts": [('172.20.0.1', 6379)],
        },
    },
}
Madisonmadlen answered 29/11, 2020 at 21:14 Comment(0)
G
2

i have the same issue, the problem was the version of my python and also of the channels. the tutorial woks perfectly with python=3.6, channels-redis 2.3.1 and daphne 2.0.2, channels =2.0. You can follow the channels documentation of the channels version you have install.

Germaun answered 24/7, 2020 at 6:26 Comment(0)
G
0

I had a similar error with a Python FastAPI app running in a Docker container trying to connect to another container with http3.AsyncClient which also uses asyncio library.

One option which worked was to use IP of a container to which trying to connect. Get container id with docker ps then get container's IP with one of the options:

docker inspect -f "{{range.NetworkSettings.Networks}}{{.IPAddress}}{{end}}" containerId

docker inspect -f "{{ .NetworkSettings.IPAddress }}" containerId

docker inspect containerId | grep IPAddress

The other was to run container on a host network which lets a container share your host’s networking stack

docker run --network=host --name myContainer -p 8080:8080 -d myImageName

then 127.0.0.1 can be used for a host to connect to.

Gourmand answered 28/1, 2022 at 18:15 Comment(0)
G
0

Whether install Redis on your container manually and set it up with Django or set up docker-compose to do that for you.

docker run -p 6379:6379 -d redis:latest

or

My docker-compose.yml file

version: "3.9"
services:
  django:
    build:
      context: .
    image: django-chatapp-image
    container_name: django-chatapp
    volumes:
      - ./:/app
      - /virtual-env
    ports:
      - 8000:8000
    environment:
      - SOME_KEY=SOME_VAL
    depends_on:
      - redis

  redis:
    image: redis:alpine
    ports:
      - "6379:6379"
    volumes:
      - ./redisdata:/data

When you set up a service for redis the name of your service will be your host.

CHANNEL_LAYERS = {
    'default': {
        'BACKEND': 'channels_redis.core.RedisChannelLayer',
        'CONFIG': {
            "hosts": [('redis', 6379)],
        },
    },
}

know more

Grandpapa answered 1/3, 2022 at 7:3 Comment(0)
C
0

Okay, my search query was ConnectionRefusedError: [Errno 111] Connect call failed ('127.0.0.1', 5432) and google took me here. So, if anyone is looking for that issue, assuming,

  1. You are trying to run your dockerised app
  2. You know it is properly configured with postgress docker container
  3. In your localhost

try,

docker run --network="host" container_id_or_name
Coastal answered 18/3, 2022 at 6:14 Comment(0)
G
0

Follow the Tutorial:

docker run -p 6379:6379 -d redis:5 before and then: python3 manage.py runserver

If you restart your system you need to run docker run -p 6379:6379 -d redis:5 again before python3 manage.py runserver

Greenebaum answered 14/4, 2022 at 0:58 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.