python - Celery 任务未在 docker-compose 中运行

标签 python django docker redis celery

我有一个 docker-compose,其中包含三个组件:app、celery 和 redis。这些是在 DjangoRest 中实现的。

我在 stackoverflow 上多次看到这个问题,并尝试了列出的所有解决方案。但是,celery 任务没有运行。

celery 的行为与应用程序相同,即启动 django 项目,但不运行任务。

docker-compose.yml

version: "3.8"
services:
  app:
    build: .
    volumes:
      - .:/django
    ports:
      - 8000:8000
    image: app:django
    container_name: myapp
    command: python manage.py runserver 0.0.0.0:8000
    depends_on:
      - redis
  redis:
    image: redis:alpine
    container_name: redis
    ports:
      - 6379:6379
    volumes:
      - ./redis/data:/data
    restart: always
    environment:
      - REDIS_PASSWORD=
    healthcheck:
      test: redis-cli ping
      interval: 1s
      timeout: 3s
      retries: 30

  celery:
    image: celery:3.1
    container_name: celery
    restart: unless-stopped
    build:
      context: .
      dockerfile: Dockerfile
    command: celery -A myapp worker -l INFO -c 8
    volumes:
      - .:/django
    depends_on:
      - redis
      - app
    links:
      - redis

DockerFile

FROM python:3.9

RUN useradd --create-home --shell /bin/bash django
USER django

ENV DockerHOME=/home/django

RUN mkdir -p $DockerHOME
ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1
ENV PIP_DISABLE_PIP_VERSION_CHECK 1

USER root
RUN wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key add -
RUN sh -c 'echo "deb [arch=amd64] http://dl.google.com/linux/chrome/deb/ stable main" >> /etc/apt/sources.list.d/google-chrome.list'
RUN apt-get -y update
RUN apt-get install -y google-chrome-stable

USER django
WORKDIR /home/django
COPY requirements.txt ./

# set path
ENV PATH=/home/django/.local/bin:$PATH

# Upgrade pip and install requirements.txt
RUN pip install --upgrade pip
RUN pip install -r requirements.txt
COPY . .

EXPOSE 8000

# entrypoint
ENTRYPOINT ["/bin/bash", "-e", "docker-entrypoint.sh"]

docker-entrypoint.sh

# run migration first
python manage.py migrate

# create test dev user and test superuser
echo 'import create_test_users' | python manage.py shell

# start the server
python manage.py runserver 0.0.0.0:8000

celery.py
from __future__ import absolute_import
import os
from celery import Celery
from django.conf import settings

os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'myapp.settings')
app = Celery('myapp', broker='redis://redis:6379')
app.config_from_object('django.conf:settings', namespace='CELERY')
app.autodiscover_tasks(lambda: settings.INSTALLED_APPS)

@app.task(bind=True)
def debug_task(self):
    print('Request: {0!r}'.format(self.request))

设置.py
CELERY_BROKER_URL     = os.getenv('REDIS_URL') # "redis://redis:6379"
CELERY_RESULT_BACKEND = os.getenv('REDIS_URL') # ""redis://redis:6379"
CELERY_ACCEPT_CONTENT = ['application/json']
CELERY_TASK_SERIALIZER = 'json'
CELERY_RESULT_SERIALIZER = 'json'
CELERY_TIMEZONE = 'Africa/Nairobi'

最佳答案

您的 docker-entrypoint.sh 脚本无条件运行 Django 服务器。由于您将其声明为图像的 ENTRYPOINT,因此 Compose command:passed to it as arguments但您的脚本会忽略这些。

解决此问题的最佳方法是传递特定命令 - “运行 Django 服务器”、“运行 Celery Worker” - 作为 Dockerfile CMD 或 Compose 命令:.入口点脚本以 shell 命令 exec "$@" 结束以运行该命令。

#!/bin/sh
python manage.py migrate
echo 'import create_test_users' | python manage.py shell

# run the container CMD
exec "$@"

在您的 Dockerfile 中,您需要声明默认的 CMD

ENTRYPOINT ["./docker-entrypoint.sh"]
CMD python manage.py runserver 0.0.0.0:8000

现在,在您的 Compose 设置中,如果您未指定 command:,它将使用默认的 CMD,但如果您这样做,则会运行该命令。在这两种情况下,您的入口点脚本都会运行,但当它到达最后的 exec "$@" 行时,它将运行提供的命令。

这意味着您可以从 app 容器中删除 command: 覆盖。 (您确实需要将其保留给 Celery 容器。)您可以通过删除 image:container_name: 设置来进一步简化此设置(Compose 将为这两个设置选择合理的默认值)其中)和隐藏图像内容的 volumes: 安装。

关于python - Celery 任务未在 docker-compose 中运行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72587417/

相关文章:

python xml : xpath for elements with childer with specific attribute values

django - Django使用外键的post_save信号

postgresql - 在Docker中运行PostgreSql

python - 将 Django 管理站点用于模型的特定实例

python - Django:使用 PIL、Amazon S3 和 Boto 调整图像大小和上传

python - django - 使 datetimefield 接受 unix 时间戳

python - 在 Docker 容器中找不到模块

amazon-web-services - 如何在AWS Lambda上安装fontconfig?

python - 无法使用 zip() 从列表列表中获取平均颜色(红色、绿色、蓝色)

python - Django "set_password()"函数不工作