Задачи сельдерея не выполняются в контейнере docker

#django #docker #django-rest-framework #docker-compose

#django #docker #django-rest-framework #docker-compose

Вопрос:

В Django я хочу выполнить задачу сельдерея (скажем, добавить 2 числа), когда пользователь загружает новый файл /media . Что я сделал, так это использовал signals so при сохранении связанного объекта загрузки, задача сельдерея будет запущена.

Вот мой код и конфигурация Docker:

signals.py

 from django.db.models.signals import post_save
from django.dispatch import receiver
from core.models import Upload
from core.tasks import add_me

def upload_save(sender, instance, signal, *args, **kwargs):
    print("IN UPLOAD SIGNAL") # <----- LOGS PRINT UP TO HERE, IN CONTAINERS
    add_me.delay(10)    

post_save.connect(upload_save, sender=Upload) # My post save signal
 

tasks.py

 from celery import shared_task

@shared_task(ignore_result=True, max_retries=3)    
def add_me(upload_id):
    print('In celery') # <----- This is not printed when in Docker!
    return upload_id   20
 

views.py

 class UploadView(mixins.CreateModelMixin, generics.GenericAPIView):

    serializer_class = UploadSerializer

    def post(self, request, *args, **kwargs):
        serializer = UploadSerializer(data=request.data)
        print("SECOND AFTER")
        print(request.data) <------ I can see my file name here
        if serializer.is_valid():
            print("THIRD AFTER") <------ This is printer OK in all cases
            serializer.save()
            print("FOURTH AFTER") <----- But this is not printed when in Docker!
            return response.Response(
                {"Message": "Your file was  uploaded"},
                status=status.HTTP_201_CREATED,
            )

        return response.Response(
            {"Message": "Failure", "Errors": serializer.errors},
            status=status.HTTP_403_FORBIDDEN,
        )
 

docker-compose.yml

 version: "3.8"
services:
  db:
    # build: ./database_docker/
    image: postgres
    ports:
      - "5432:5432"
    environment:
      POSTGRES_DB: test_db
      POSTGRES_USER: test_user
      POSTGRES_PASSWORD: test_pass
    # volumes:
    #   - media:/code/media

  web:
    build: ./docker/
    command: bash -c "python manage.py migrate --noinput amp;amp; python manage.py runserver 0.0.0.0:8000"
    volumes:
      - .:/code
      - media:/code/media
    ports:
      - "8000:8000"
    depends_on:
      - db

  rabbitmq:
    image: rabbitmq:3.6.10
    volumes:
      - media:/code/media

  worker:
    build: ./docker/
    command: celery -A example_worker worker --loglevel=debug -n worker1.%h
    volumes:
      - .:/code
      - media:/code/media
    depends_on:
      - db
      - rabbitmq
volumes:
  media: 
 

Dockerfile

 FROM python:latest
ENV PYTHONUNBUFFERED=1
WORKDIR /code
COPY requirements.txt /code/
RUN pip3 install -r requirements.txt
COPY . /code/
WORKDIR /code
 

Все работает нормально, когда не в Docker.

Проблема в том, что когда я развертываю вышеупомянутое в Docker и пытаюсь загрузить файл, запрос никогда не завершается, хотя файл загружен в media папку (подтвердил это, обратившись к его содержимому как web в контейнерах, так и worker в контейнерах).

Более конкретно, кажется, что задача сельдерея не выполняется (завершена?), А код после serializer.save() никогда не достигается.

Когда я удаляю сигнал (таким образом, задача сельдерея не запускается), все в порядке. Может кто-нибудь мне помочь?

Ответ №1:

Я только что понял это. Оказывается, мне нужно добавить следующее в __init__.py мое приложение.

 from .celery import app as celery_app

__all__ = ("celery_app",)
 

Не знаю, почему все работает гладко без этого фрагмента кода, когда я не использую контейнеры…