我有一个 django 应用程序,我想使用docker run
命令运行redis
和celery
在我使用 docker 撰写文件构建映像之后 我在不同的窗口电源外壳上运行两个命令
docker run -it -p 6379:6379 redis
docker run -it image_celery
我的芹菜电源外壳无法检测到 Redis
[2020-02-08 13:08:44,686:错误/主进程] 消费者:无法连接到 redis://redis:6379/1:错误-2连接到redis:6379。名称或服务未知.. 在 2.00 秒后重试...
version: '3'
services:
the-redis:
image: redis:3.2.7-alpine
ports:
- "6379:6379"
volumes:
- ../data/redis:/data
celery_5:
build:
context: ./mltrons_backend
dockerfile: Dockerfile_celery
volumes:
- ./mltrons_backend:/code
- /tmp:/code/static
depends_on:
- the-redis
deploy:
replicas: 4
resources:
limits:
memory: 25g
restart_policy:
condition: on-failure
volumes:
db_data:
external: true
Dockerfile_celery
FROM python:3.6
ENV PYTHONUNBUFFERED 1
# Install Java
RUN apt-get -y update &&
apt install -y openjdk-11-jdk &&
apt-get install -y ant &&
apt-get clean &&
rm -rf /var/lib/apt/lists/ &&
rm -rf /var/cache/oracle-jdk11-installer;
ENV JAVA_HOME /usr/lib/jvm/java-11-openjdk-amd64/
RUN mkdir /code
WORKDIR /code
ADD requirements.txt /code/
RUN pip install -r requirements.txt
ADD . /code
ENV REDIS_HOST=redis://the-redis
ENV REDIS_PORT=6379
RUN pip install --upgrade 'sentry-sdk==0.7.10'
ENTRYPOINT celery -A mlbot_webservices worker -c 10 -l info
EXPOSE 8102
celery.py
from __future__ import absolute_import, unicode_literals
import os
from celery import Celery
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'mlbot_webservices.settings')
app = Celery('mltrons_training')
app.config_from_object('django.conf:settings', namespace='CELERY')
app.autodiscover_tasks()
@app.task(bind=True)
def debug_task(self):
print('Request: {0!r}'.format(self.request))
settings.py
CELERY_BROKER_URL = 'redis://the-redis:6379/'
CELERY_RESULT_BACKEND = 'redis://the-redis:6379/'
CELERY_ACCEPT_CONTENT = ['application/json']
CELERY_RESULT_SERIALIZER = 'json'
CELERY_TASK_SERIALIZER = 'json'
这是意料之中的,因为当你像你一样启动容器(docker run IMAGE
(,容器使用Docker的默认桥接网络。
您可以通过检查该网络来检查它:docker network inspect bridge
。
默认网桥不接受按容器名称对容器进行网络解析,就像您所做的那样 (redis
(。
此外,容器的默认名称不是映像名称,而是 docker 生成的名称。
这就是为什么您在运行时收到该错误的原因:
无法连接到 redis://redis:6379/1
请注意,您仍可以通过其 IP 地址引用属于默认网桥的容器,但这通常是不可取的,因为这会从客户端对它们进行硬编码。
这适用于 Docker 撰写,因为:
默认情况下,Compose 会为应用设置单个网络。每 服务的容器加入默认网络,并且两者兼而有之 可由该网络上的其他容器访问,并可由 它们的主机名与容器名称相同。
为了能够通过容器名称与docker run
进行通信,您需要 :
- 将这些容器添加到同一个网络中,而不是 Docker
提供的默认容器 - 为您要引用的容器提供一个显式名称(同时对两个容器执行此操作可以更轻松地监控/管理它(。
例如,创建一个用户定义的桥接网络,并在启动容器时将容器添加到其中:
docker network create -d bridge my-bridge-network
docker run -it -p 6379:6379 --network=my-bridge-network --name=redis redis
docker run -it --network=my-bridge-network --name=celery image_celery