Docker 运行 image_celery 无法检测到 redis

Docker run image_celery not able to detect redis

我有一个 Django 应用程序,我想 运行 rediscelery 使用 docker run 命令

在我使用 docker-compose 文件构建图像之后 我 运行 两个命令在不同的 windows powershell

  1. docker run -it -p 6379:6379 redis
  2. docker run -it image_celery

我的 celery powershell 无法检测到 redis

[2020-02-08 13:08:44,686: ERROR/MainProcess] consumer: Cannot connect to redis://redis:6379/1: Error -2 connecting to redis:6379. Name or service not known.. Trying again in 2.00 seconds...

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.
生成的名称 这就是为什么您在运行时遇到该错误的原因:

Cannot connect to redis://redis:6379/1

请注意,您仍然可以通过 IP 地址引用属于默认网桥的容器,但这通常是不可取的,因为从客户端对它们进行硬编码。

That works with Docker compose because :

By default Compose sets up a single network for your app. Each container for a service joins the default network and is both reachable by other containers on that network, and discoverable by them at a hostname identical to the container name.

为了能够通过容器名称与 docker run 进行通信,您需要:
- 在同一个网络中添加这些容器,而不是 Docker
提供的默认容器 - 给你想要引用的容器一个明确的名称(同时对两个容器都这样做有利于 monitor/manager 更简单)。

例如,创建一个用户定义的桥接网络并在启动时将容器添加到其中:

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