问题描述
我按照django频道教程构建了一个简单的聊天应用程序. https://channels.readthedocs.io/en/latest/tutorial/part_1.html ,它可以在没有docker的情况下使用Redis在我的本地计算机上运行.
I follow the django channels tutorial to build a simple chat app.https://channels.readthedocs.io/en/latest/tutorial/part_1.html,it can work on my local machine with redis without docker.
然后我现在想通过docker compose文件将其放入docker容器中,但是似乎应用无法连接到redis容器,我已经尝试和Google进行了两天的尝试,但是似乎所有方法都无法使用.
then now i want to put it into docker containers by docker compose file, but seems app cannot connect to redis container, i already try and google for two days, but seems all methods cannot work.
所以想在这里寻求帮助
文件夹结构
my_project
- mysite(django app)
- ... somefolder and files
- docker-compose.yml
- Dockfile
- requirements.txt
docker-compose.yml
version: '3'
services:
app:
build:
# current directory
context: .
ports:
#host to image
- "8000:8000"
volumes:
# map directory to image, which means if something changed in
# current directory, it will automatically reflect on image,
# don't need to restart docker to get the changes into effect
- ./mysite:/mysiteRoot/mysite
command: >
sh -c "
python3 manage.py makemigrations &&
python3 manage.py migrate &&
python3 manage.py runserver 0.0.0.0:8000"
depends_on:
- redis
redis:
image: redis:5.0.5-alpine
ports:
#host to image
- "6379:6379"
Dockfile
FROM python:3.7-alpine
MAINTAINER Aaron Wei.
ENV PYTHONUNBUFFERED 1
EXPOSE 8000
# Setup directory structure
RUN mkdir /mysiteRoot
WORKDIR /mysiteRoot/mysite/
# Install dependencies
COPY ./requirements.txt /mysiteRoot/requirements.txt
RUN apk add --update --no-cache postgresql-client
RUN apk add --update --no-cache --virtual .tmp-build-deps \
gcc libc-dev linux-headers postgresql-dev
RUN apk add build-base python-dev py-pip jpeg-dev zlib-dev
ENV LIBRARY_PATH=/lib:/usr/lib
RUN pip install -r /mysiteRoot/requirements.txt
RUN apk del .tmp-build-deps
# Copy application
COPY ./mysite/ /mysiteRoot/mysite/
RUN adduser -D user
USER user
Django设置文件
"""
Django settings for mysite project.
Generated by 'django-admin startproject' using Django 2.2.2.
For more information on this file, see
https://docs.djangoproject.com/en/2.2/topics/settings/
For the full list of settings and their values, see
https://docs.djangoproject.com/en/2.2/ref/settings/
"""
import os
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/2.2/howto/deployment/checklist/
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = 's0d^&2@s^126#6dsm7u4-t9pg03)if$dq##xxouht)#%#=o)r0'
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True
ALLOWED_HOSTS = ['0.0.0.0']
# Application definition
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'channels',
'chat',
]
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
ROOT_URLCONF = 'mysite.urls'
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
WSGI_APPLICATION = 'mysite.wsgi.application'
ASGI_APPLICATION = 'mysite.routing.application'
CHANNEL_LAYERS = {
'default': {
'BACKEND': 'channels_redis.core.RedisChannelLayer',
'CONFIG': {
"hosts": [('0.0.0.0', 6379)],
},
},
}
# Database
# https://docs.djangoproject.com/en/2.2/ref/settings/#databases
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
}
}
# Password validation
# https://docs.djangoproject.com/en/2.2/ref/settings/#auth-password-validators
AUTH_PASSWORD_VALIDATORS = [
{
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
},
]
# Internationalization
# https://docs.djangoproject.com/en/2.2/topics/i18n/
LANGUAGE_CODE = 'en-us'
TIME_ZONE = 'UTC'
USE_I18N = True
USE_L10N = True
USE_TZ = True
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/2.2/howto/static-files/
STATIC_URL = '/static/'
docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
7966fe4962f7 tourmama_copy_app "sh -c '\n pyth…" 21 minutes ago Up 20 minutes 0.0.0.0:8000->8000/tcp tourmama_copy_app_1
61446d04c4b2 redis:5.0.5-alpine "docker-entrypoint.s…" 27 minutes ago Up 20 minutes 0.0.0.0:6379->6379/tcp tourmama_copy_redis_1
然后控制台中的错误显示:
Then the error in console shows :
app_1 | HTTP GET /chat/dadas/ 200 [0.01, 172.19.0.1:39468]
app_1 | WebSocket HANDSHAKING /ws/chat/dadas/ [172.19.0.1:39470]
app_1 | Exception inside application: [Errno 111] Connect call failed ('0.0.0.0', 6379)
app_1 | File "/usr/local/lib/python3.7/site-packages/channels/sessions.py", line 179, in __call__
app_1 | return await self.inner(receive, self.send)
app_1 | File "/usr/local/lib/python3.7/site-packages/channels/middleware.py", line 41, in coroutine_call
app_1 | await inner_instance(receive, send)
app_1 | File "/usr/local/lib/python3.7/site-packages/channels/consumer.py", line 59, in __call__
app_1 | [receive, self.channel_receive], self.dispatch
app_1 | File "/usr/local/lib/python3.7/site-packages/channels/utils.py", line 59, in await_many_dispatch
app_1 | await task
app_1 | File "/usr/local/lib/python3.7/site-packages/channels_redis/core.py", line 425, in receive
app_1 | real_channel
app_1 | File "/usr/local/lib/python3.7/site-packages/channels_redis/core.py", line 477, in receive_single
app_1 | index, channel_key, timeout=self.brpop_timeout
app_1 | File "/usr/local/lib/python3.7/site-packages/channels_redis/core.py", line 324, in _brpop_with_clean
app_1 | async with self.connection(index) as connection:
app_1 | File "/usr/local/lib/python3.7/site-packages/channels_redis/core.py", line 813, in __aenter__
app_1 | self.conn = await self.pool.pop()
app_1 | File "/usr/local/lib/python3.7/site-packages/channels_redis/core.py", line 70, in pop
app_1 | conns.append(await aioredis.create_redis(**self.host, loop=loop))
app_1 | File "/usr/local/lib/python3.7/site-packages/aioredis/commands/__init__.py", line 178, in create_redis
app_1 | loop=loop)
app_1 | File "/usr/local/lib/python3.7/site-packages/aioredis/connection.py", line 108, in create_connection
app_1 | timeout, loop=loop)
app_1 | File "/usr/local/lib/python3.7/asyncio/tasks.py", line 388, in wait_for
app_1 | return await fut
app_1 | File "/usr/local/lib/python3.7/site-packages/aioredis/stream.py", line 19, in open_connection
app_1 | lambda: protocol, host, port, **kwds)
app_1 | File "/usr/local/lib/python3.7/asyncio/base_events.py", line 959, in create_connection
app_1 | raise exceptions[0]
app_1 | File "/usr/local/lib/python3.7/asyncio/base_events.py", line 946, in create_connection
app_1 | await self.sock_connect(sock, address)
app_1 | File "/usr/local/lib/python3.7/asyncio/selector_events.py", line 464, in sock_connect
app_1 | return await fut
app_1 | File "/usr/local/lib/python3.7/asyncio/selector_events.py", line 494, in _sock_connect_cb
app_1 | raise OSError(err, f'Connect call failed {address}')
app_1 | [Errno 111] Connect call failed ('0.0.0.0', 6379)
app_1 | WebSocket DISCONNECT /ws/chat/dadas/ [172.19.0.1:39470]
有人知道如何从应用程序连接到Redis容器吗?谢谢!
is anyone has any idea how to connect to redis container from app?thank you !
推荐答案
您应更改:
CHANNEL_LAYERS = {
'default': {
'BACKEND': 'channels_redis.core.RedisChannelLayer',
'CONFIG': {
"hosts": [('0.0.0.0', 6379)],
},
},
}
到
CHANNEL_LAYERS = {
'default': {
'BACKEND': 'channels_redis.core.RedisChannelLayer',
'CONFIG': {
"hosts": [('redis', 6379)],
},
},
}
在您的 Django设置文件
中.
通过compose设置容器时,它们都已连接到compose创建的默认网络.在这种情况下, redis
是 redis
容器的DNS名称,它将自动解析为容器ip
When you set up containers from compose they are all connected to the default network created by compose. redis
is in this case the DNS name of redis
container and will be resolved to container ip automatically
这篇关于无法从应用程序容器连接到Redis容器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!