无法从应用程序容器连接到 Redis 容器

Aar*_*ron 4 redis docker

我按照 django Channels 教程构建了一个简单的聊天应用程序。 \n https://channels.readthedocs.io/en/latest/tutorial/part_1.html \n, \n它可以在我的本地计算机上使用 redis 运行,无需 docker 。

\n\n

然后现在我想通过docker compose文件将其放入docker容器中,但似乎应用程序无法连接到redis容器,我已经尝试和google了两天,但似乎所有方法都无法工作。

\n\n

所以想在这里寻求帮助

\n\n

文件夹结构

\n\n
my_project\n  - mysite(django app)\n     - ... somefolder and files\n  - docker-compose.yml\n  - Dockfile\n  - requirements.txt\n
Run Code Online (Sandbox Code Playgroud)\n\n

docker-compose.yml

\n\n
version: \'3\'\n\nservices:\n  app:\n    build:\n      # current directory\n      context: .\n    ports:\n      #host to image\n      - "8000:8000"\n    volumes:\n      # map directory to image, which means if something changed in\n      # current directory, it will automatically reflect on image,\n      # don\'t need to restart docker to get the changes into effect\n      - ./mysite:/mysiteRoot/mysite\n    command: >\n      sh -c "\n             python3 manage.py makemigrations &&\n             python3 manage.py migrate &&\n             python3 manage.py runserver 0.0.0.0:8000"\n\n    depends_on:\n      - redis\n\n  redis:\n    image: redis:5.0.5-alpine\n    ports:\n      #host to image\n      - "6379:6379"\n
Run Code Online (Sandbox Code Playgroud)\n\n

码头文件

\n\n
FROM python:3.7-alpine\nMAINTAINER Aaron Wei.\n\nENV PYTHONUNBUFFERED 1\n\nEXPOSE 8000\n\n# Setup directory structure\nRUN mkdir /mysiteRoot\nWORKDIR /mysiteRoot/mysite/\n\n# Install dependencies\nCOPY ./requirements.txt /mysiteRoot/requirements.txt\nRUN apk add --update --no-cache postgresql-client\nRUN apk add --update --no-cache --virtual .tmp-build-deps \\\n      gcc libc-dev linux-headers postgresql-dev\nRUN apk add build-base python-dev py-pip jpeg-dev zlib-dev\nENV LIBRARY_PATH=/lib:/usr/lib\nRUN pip install -r /mysiteRoot/requirements.txt\nRUN apk del .tmp-build-deps\n\n# Copy application\nCOPY ./mysite/ /mysiteRoot/mysite/\n\nRUN adduser -D user\nUSER user\n
Run Code Online (Sandbox Code Playgroud)\n\n

Django 设置文件

\n\n
"""\nDjango settings for mysite project.\n\nGenerated by \'django-admin startproject\' using Django 2.2.2.\n\nFor more information on this file, see\nhttps://docs.djangoproject.com/en/2.2/topics/settings/\n\nFor the full list of settings and their values, see\nhttps://docs.djangoproject.com/en/2.2/ref/settings/\n"""\n\nimport os\n\n# Build paths inside the project like this: os.path.join(BASE_DIR, ...)\nBASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))\n\n\n# Quick-start development settings - unsuitable for production\n# See https://docs.djangoproject.com/en/2.2/howto/deployment/checklist/\n\n# SECURITY WARNING: keep the secret key used in production secret!\nSECRET_KEY = \'s0d^&2@s^126#6dsm7u4-t9pg03)if$dq##xxouht)#%#=o)r0\'\n\n# SECURITY WARNING: don\'t run with debug turned on in production!\nDEBUG = True\n\nALLOWED_HOSTS = [\'0.0.0.0\']\n\n\n# Application definition\n\nINSTALLED_APPS = [\n    \'django.contrib.admin\',\n    \'django.contrib.auth\',\n    \'django.contrib.contenttypes\',\n    \'django.contrib.sessions\',\n    \'django.contrib.messages\',\n    \'django.contrib.staticfiles\',\n    \'channels\',\n    \'chat\',\n]\n\nMIDDLEWARE = [\n    \'django.middleware.security.SecurityMiddleware\',\n    \'django.contrib.sessions.middleware.SessionMiddleware\',\n    \'django.middleware.common.CommonMiddleware\',\n    \'django.middleware.csrf.CsrfViewMiddleware\',\n    \'django.contrib.auth.middleware.AuthenticationMiddleware\',\n    \'django.contrib.messages.middleware.MessageMiddleware\',\n    \'django.middleware.clickjacking.XFrameOptionsMiddleware\',\n]\n\nROOT_URLCONF = \'mysite.urls\'\n\nTEMPLATES = [\n    {\n        \'BACKEND\': \'django.template.backends.django.DjangoTemplates\',\n        \'DIRS\': [],\n        \'APP_DIRS\': True,\n        \'OPTIONS\': {\n            \'context_processors\': [\n                \'django.template.context_processors.debug\',\n                \'django.template.context_processors.request\',\n                \'django.contrib.auth.context_processors.auth\',\n                \'django.contrib.messages.context_processors.messages\',\n            ],\n        },\n    },\n]\n\nWSGI_APPLICATION = \'mysite.wsgi.application\'\nASGI_APPLICATION = \'mysite.routing.application\'\n\nCHANNEL_LAYERS = {\n    \'default\': {\n        \'BACKEND\': \'channels_redis.core.RedisChannelLayer\',\n        \'CONFIG\': {\n            "hosts": [(\'0.0.0.0\', 6379)],\n        },\n    },\n}\n\n# Database\n# https://docs.djangoproject.com/en/2.2/ref/settings/#databases\n\nDATABASES = {\n    \'default\': {\n        \'ENGINE\': \'django.db.backends.sqlite3\',\n        \'NAME\': os.path.join(BASE_DIR, \'db.sqlite3\'),\n    }\n}\n\n\n# Password validation\n# https://docs.djangoproject.com/en/2.2/ref/settings/#auth-password-validators\n\nAUTH_PASSWORD_VALIDATORS = [\n    {\n        \'NAME\': \'django.contrib.auth.password_validation.UserAttributeSimilarityValidator\',\n    },\n    {\n        \'NAME\': \'django.contrib.auth.password_validation.MinimumLengthValidator\',\n    },\n    {\n        \'NAME\': \'django.contrib.auth.password_validation.CommonPasswordValidator\',\n    },\n    {\n        \'NAME\': \'django.contrib.auth.password_validation.NumericPasswordValidator\',\n    },\n]\n\n\n# Internationalization\n# https://docs.djangoproject.com/en/2.2/topics/i18n/\n\nLANGUAGE_CODE = \'en-us\'\n\nTIME_ZONE = \'UTC\'\n\nUSE_I18N = True\n\nUSE_L10N = True\n\nUSE_TZ = True\n\n\n# Static files (CSS, JavaScript, Images)\n# https://docs.djangoproject.com/en/2.2/howto/static-files/\n\nSTATIC_URL = \'/static/\'\n\n
Run Code Online (Sandbox Code Playgroud)\n\n

码头工人

\n\n
CONTAINER ID        IMAGE                COMMAND                   CREATED             STATUS              PORTS                    NAMES\n7966fe4962f7        tourmama_copy_app    "sh -c \'\\n       pyth\xe2\x80\xa6"   21 minutes ago      Up 20 minutes       0.0.0.0:8000->8000/tcp   tourmama_copy_app_1\n61446d04c4b2        redis:5.0.5-alpine   "docker-entrypoint.s\xe2\x80\xa6"    27 minutes ago      Up 20 minutes       0.0.0.0:6379->6379/tcp   tourmama_copy_redis_1\n
Run Code Online (Sandbox Code Playgroud)\n\n

然后控制台中的错误显示:

\n\n
app_1    | HTTP GET /chat/dadas/ 200 [0.01, 172.19.0.1:39468]\napp_1    | WebSocket HANDSHAKING /ws/chat/dadas/ [172.19.0.1:39470]\napp_1    | Exception inside application: [Errno 111] Connect call failed (\'0.0.0.0\', 6379)\napp_1    |   File "/usr/local/lib/python3.7/site-packages/channels/sessions.py", line 179, in __call__\napp_1    |     return await self.inner(receive, self.send)\napp_1    |   File "/usr/local/lib/python3.7/site-packages/channels/middleware.py", line 41, in coroutine_call\napp_1    |     await inner_instance(receive, send)\napp_1    |   File "/usr/local/lib/python3.7/site-packages/channels/consumer.py", line 59, in __call__\napp_1    |     [receive, self.channel_receive], self.dispatch\napp_1    |   File "/usr/local/lib/python3.7/site-packages/channels/utils.py", line 59, in await_many_dispatch\napp_1    |     await task\napp_1    |   File "/usr/local/lib/python3.7/site-packages/channels_redis/core.py", line 425, in receive\napp_1    |     real_channel\napp_1    |   File "/usr/local/lib/python3.7/site-packages/channels_redis/core.py", line 477, in receive_single\napp_1    |     index, channel_key, timeout=self.brpop_timeout\napp_1    |   File "/usr/local/lib/python3.7/site-packages/channels_redis/core.py", line 324, in _brpop_with_clean\napp_1    |     async with self.connection(index) as connection:\napp_1    |   File "/usr/local/lib/python3.7/site-packages/channels_redis/core.py", line 813, in __aenter__\napp_1    |     self.conn = await self.pool.pop()\napp_1    |   File "/usr/local/lib/python3.7/site-packages/channels_redis/core.py", line 70, in pop\napp_1    |     conns.append(await aioredis.create_redis(**self.host, loop=loop))\napp_1    |   File "/usr/local/lib/python3.7/site-packages/aioredis/commands/__init__.py", line 178, in create_redis\napp_1    |     loop=loop)\napp_1    |   File "/usr/local/lib/python3.7/site-packages/aioredis/connection.py", line 108, in create_connection\napp_1    |     timeout, loop=loop)\napp_1    |   File "/usr/local/lib/python3.7/asyncio/tasks.py", line 388, in wait_for\napp_1    |     return await fut\napp_1    |   File "/usr/local/lib/python3.7/site-packages/aioredis/stream.py", line 19, in open_connection\napp_1    |     lambda: protocol, host, port, **kwds)\napp_1    |   File "/usr/local/lib/python3.7/asyncio/base_events.py", line 959, in create_connection\napp_1    |     raise exceptions[0]\napp_1    |   File "/usr/local/lib/python3.7/asyncio/base_events.py", line 946, in create_connection\napp_1    |     await self.sock_connect(sock, address)\napp_1    |   File "/usr/local/lib/python3.7/asyncio/selector_events.py", line 464, in sock_connect\napp_1    |     return await fut\napp_1    |   File "/usr/local/lib/python3.7/asyncio/selector_events.py", line 494, in _sock_connect_cb\napp_1    |     raise OSError(err, f\'Connect call failed {address}\')\napp_1    |   [Errno 111] Connect call failed (\'0.0.0.0\', 6379)\napp_1    | WebSocket DISCONNECT /ws/chat/dadas/ [172.19.0.1:39470]\n\n\n
Run Code Online (Sandbox Code Playgroud)\n\n

有人知道如何从应用程序连接到 Redis 容器吗?\n谢谢!

\n

mic*_*alk 5

你应该改变:

CHANNEL_LAYERS = {
    'default': {
        'BACKEND': 'channels_redis.core.RedisChannelLayer',
        'CONFIG': {
            "hosts": [('0.0.0.0', 6379)],
        },
    },
}
Run Code Online (Sandbox Code Playgroud)

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

在你的Django settings file

当您从 compose 设置容器时,它们都连接到 compose 创建的默认网络。redis在本例中是容器的 DNS 名称redis,并将自动解析为容器 ip