django

Python-Celery in Windows with Docker managing

  • четверг, 27 февраля 2020 г. в 00:28:19
https://habr.com/ru/post/490040/
  • Python
  • Django
  • Разработка под Windows


Для того чтобы 'адекватно' отладить Celery из-под Windows существует несколько путей таких как:

> celery worker --app=demo_app.core --pool=solo --loglevel=INFO

Но, по факту для нормальной разработки нужна Unix-система. Если у Вас нет возможности использовать её как родную, то стоит задуматься…) Ну а если честно, то выход всегда есть и это Docker, а также WSL. Если Вы используете такие «крутые» IDE, как PyCharm, то всё так же усложняется, ведь тогда при использовании интерпретатора с источником из WSL после установки пакета через pip скелет проекта придётся обновлять вручную из-за проблем с индексацией.

Но с Docker все по-другому. Для крутого менеджмента нам понадобится Windows 10 Pro, так как Home-версия не поддерживает виртуализацию.

Теперь устанавливаем и проверяем Docker. После того как это произойдет в трее, появится соответствующий значок.

image

Дальше создаем и запускаем проект на Django. Здесь я использую версию 2.2. Будет структура, похожа на такую:

image

После устанавливаем Celery and Redis в качестве брокера.

Теперь добавим немного кода для проверки:

# core/settings.py 
CELERY_BROKER_URL = 'redis://demo_app_redis:6379'
CELERY_ACCEPT_CONTENT = ['json'] 
CELERY_TASK_SERIALIZER = 'json'

# core/celery.py
from __future__ import absolute_import, unicode_literals
import os
from celery import Celery

os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'core.settings')
app = Celery('core')
app.config_from_object('django.conf:settings', namespace='CELERY')
app.autodiscover_tasks()

# core/__init__.py
from __future__ import absolute_import, unicode_literals
from .celery import app as celery_app

__all__ = ('celery_app',)

Добавим новое django-приложение в котором будут наши задачи и добавим новый файл:

# app/tasks.py
from celery.task import periodic_task
from datetime import timedelta

@periodic_task(run_every=(timedelta(seconds=5)), name='hello')
def hello():
    print("Hello there")

Далее создаём Dockerfile и docker-compose.yml в корне проекта:

# Dockerfile
FROM python:3.7
RUN pip install pipenv
RUN mkdir /code
WORKDIR /code
COPY Pipfile* /code/
RUN pipenv install --system --deploy --ignore-pipfile
ADD core /code/

# docker-compose.yml
version: '3'

services:
  redis:
    image: redis
    restart: always
    container_name: 'demo_app_redis'
    command: redis-server
    ports:
      - '6379:6379'
  web:
    build: .
    restart: always
    container_name: 'demo_app_django'
    command: python manage.py runserver 0.0.0.0:8000
    volumes:
      - .:/code
    ports:
      - '8000:8000'
  celery:
    build: .
    container_name: 'demo_app_celery'
    command: celery -A core worker -B
    volumes:
      - .:/code
    links:
      - redis
    depends_on:
      - web
      - redis

И стартуем!

image

Дожидаемся установки всех зависимостей в pipenv-окружение. В конце вы должны будете увидеть что-то похоже на это:

image

Это значит, что все круто! Осуществлять контроль можно с командной строки:

image

image

Как видим у 2 образов, которые были созданы из одного Dockerfile один ID.

Но так же управлять контейнерами можно с помощью GUI:

image

image

Таким вот образом можно легко включать/выключать, перезапускать, удалять контейнера.

image