如何让celerybeat-cron任务在django应用程序的docker容器中运行



我正试图在我的django/nuxt应用程序中运行芹菜节拍任务我有独立的前端和后端目录,我使用dockercompose来构建和运行我的应用程序。(pycharm专业mac oS seria

我可以完美地运行我的任务,而无需在本地使用docker容器,但当我尝试容器化运行时,芹菜和芹菜节拍都无法保持运行。我发现网上的文档很差,甚至在西芹或码头工人的官方文档中也没有提到运行西芹&殴打码头工人有人能告诉我我的配置是否错误,或者我需要做什么才能让我的应用程序接受我的设置.py中的cronjobs吗?

我用docker-compose up-d构建容器并使用docker-compose exec django bash运行我的应用程序

有人能给我指正确的方向吗?

设置.py

import os
from configurations import Configuration, values
from datetime import timedelta
#print(os.environ)

class Base(Configuration):
DEBUG = values.BooleanValue(False)
SECRET_KEY = '2pj=b#ywty7ojkv_gd#!$!vzywakop1azlxiqxrl^r50i(nf-^'
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
DATABASES = values.DatabaseURLValue()
ALLOWED_HOSTS = []
INSTALLED_APPS = [
"django.contrib.admin",
"django.contrib.auth",
"django.contrib.contenttypes",
"django.contrib.sessions",
"django.contrib.messages",
"django.contrib.staticfiles",
"rest_framework",
"rest_framework.authtoken",
"django_celery_results" ,
"django_celery_beat" ,
"corsheaders",
"djoser",
"accounts",
"posts",
"comments",
"events",
]
MIDDLEWARE = [
"django.middleware.security.SecurityMiddleware",
"django.contrib.sessions.middleware.SessionMiddleware",
"corsheaders.middleware.CorsMiddleware",
"django.middleware.common.CommonMiddleware",
"django.middleware.csrf.CsrfViewMiddleware",
"django.contrib.auth.middleware.AuthenticationMiddleware",
"django.contrib.messages.middleware.MessageMiddleware",
"django.middleware.clickjacking.XFrameOptionsMiddleware",
]
ROOT_URLCONF = "spacenews.urls"
TEMPLATES = [
{
"BACKEND": "django.template.backends.django.DjangoTemplates",
"DIRS": [],
"APP_DIRS": True,
"OPTIONS": {
"context_processors": [
"django.template.context_processors.debug",
"django.template.context_processors.request",
"django.contrib.auth.context_processors.auth",
"django.contrib.messages.context_processors.messages",
]
},
}
]
# WSGI
WSGI_APPLICATION = "spacenews.wsgi.application"
# Password validators
AUTH_PASSWORD_VALIDATORS = [
{
"NAME": "django.contrib.auth.password_validation.UserAttributeSimilarityValidator"  # noqa
},
{
"NAME": "django.contrib.auth.password_validation.MinimumLengthValidator"
},
{
"NAME": "django.contrib.auth.password_validation.CommonPasswordValidator"
},
{
"NAME": "django.contrib.auth.password_validation.NumericPasswordValidator"
},
]
AUTH_USER_MODEL = "accounts.User"
# Internationalization
LANGUAGE_CODE = "en-us"
TIME_ZONE = "UTC"
USE_I18N = True
USE_L10N = True
USE_TZ = True
# Static files
STATIC_URL = "/static/"
# REST
REST_FRAMEWORK = {
"DEFAULT_AUTHENTICATION_CLASSES": (
"rest_framework.authentication.BasicAuthentication",
"rest_framework.authentication.SessionAuthentication",
"rest_framework.authentication.TokenAuthentication",
),
"DEFAULT_PAGINATION_CLASS": "rest_framework.pagination.PageNumberPagination",
"PAGE_SIZE": 100,
}

CELERY_BROKER_URL = 'redis://localhost:6379/'
CELERY_RESULT_BACKEND = 'redis://localhost:6379/'
#CELERYD_HIJACK_ROOT_LOGGER = False
# use json format for everything
CELERY_ACCEPT_CONTENT = ['application/json']
CELERY_TASK_SERIALIZER = 'json'
CELERY_RESULT_SERIALIZER = 'json'
CELERY_TIMEZONE = 'UTC'

CELERY_BEAT_SCHEDULE = {

'login_mb': {
'task': 'events.tasks.login_mb',
'schedule': timedelta(seconds=10),
} ,
'mb_get_events': {
'task': 'events.tasks.mb_get_events' ,
'schedule': timedelta(seconds=10) ,
} ,
}

class Development(Base):
DEBUG = values.BooleanValue(True)
CORS_ORIGIN_ALLOW_ALL = True
ALLOWED_HOSTS = ["localhost", "django","postgres","redis"]

class Production(Base):
pass

class Testing(Base):
pass

Dockerfile

FROM python:3.6
ENV PYTHONUNBUFFERED 1
#ENV C_FORCE_ROOT true
RUN apt-get update && apt-get install -y postgresql-client
ADD . /app
WORKDIR /app
COPY requirements.txt /app/requirements.txt
RUN pip install -r requirements.txt
EXPOSE 8000

docker-compose.yaml

version: '2'
services:
db:
restart: always
image: postgres
redis:
restart: always
image: redis
api:
build:
context: ./backend
environment:
- DATABASE_URL=postgres://postgres@db:5432/postgres
- CELERY_BROKER_URL=redis://localhost:6379/
- CELERY_RESULT_BACKEND =redis://localhost:6379/
- DJANGO_SECRET_KEY=seekret
volumes:
- ./backend:/app
celery:
extends:
service: api
command:
bash -c "cd spacenews && celery -A spacenews worker -B --loglevel=info"
depends_on:
- db
- redis
django:
extends:
service: api
command: ./wait-for-it.sh db:5432 -- ./spacenews/manage.py runserver 0.0.0.0:8000
ports:
- "8000:8000"
volumes:
- ./backend:/app
depends_on:
- db
- redis
- celery
- celery-beat
celery-beat:
extends:
service: api
command:
bash -c "cd backend/spacenews && celery -A spacenews beat -B --loglevel=info"
volumes:
- ./backend:/app
depends_on:
- db
- redis
- celery
nuxt:
build:
context: ./frontend
environment:
- API_URI=http://django:8000/api
command: bash -c "npm install && npm run dev"
volumes:
- ./frontend:/app
ports:
- "3000:3000"
depends_on:
- django
- redis
volumes:
pgdata:
redisdata:

堆叠式芹菜容器

Traceback (most recent call last):
File "/usr/local/lib/python3.6/site-packages/kombu/utils/objects.py", line 42, in __get__
return obj.__dict__[self.__name__]
KeyError: 'data'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/usr/local/bin/celery", line 11, in <module>
sys.exit(main())
File "/usr/local/lib/python3.6/site-packages/celery/__main__.py", line 16, in main
_main()
File "/usr/local/lib/python3.6/site-packages/celery/bin/celery.py", line 322, in main
cmd.execute_from_commandline(argv)
File "/usr/local/lib/python3.6/site-packages/celery/bin/celery.py", line 496, in execute_from_commandline
super(CeleryCommand, self).execute_from_commandline(argv)))
File "/usr/local/lib/python3.6/site-packages/celery/bin/base.py", line 275, in execute_from_commandline
return self.handle_argv(self.prog_name, argv[1:])
File "/usr/local/lib/python3.6/site-packages/celery/bin/celery.py", line 488, in handle_argv
return self.execute(command, argv)
File "/usr/local/lib/python3.6/site-packages/celery/bin/celery.py", line 420, in execute
).run_from_argv(self.prog_name, argv[1:], command=argv[0])
File "/usr/local/lib/python3.6/site-packages/celery/bin/worker.py", line 221, in run_from_argv
*self.parse_options(prog_name, argv, command))
File "/usr/local/lib/python3.6/site-packages/celery/bin/base.py", line 398, in parse_options
self.parser = self.create_parser(prog_name, command)
File "/usr/local/lib/python3.6/site-packages/celery/bin/base.py", line 414, in create_parser
self.add_arguments(parser)
File "/usr/local/lib/python3.6/site-packages/celery/bin/worker.py", line 277, in add_arguments
default=conf.worker_state_db,
File "/usr/local/lib/python3.6/site-packages/celery/utils/collections.py", line 126, in __getattr__
return self[k]
File "/usr/local/lib/python3.6/site-packages/celery/utils/collections.py", line 429, in __getitem__
return getitem(k)
File "/usr/local/lib/python3.6/site-packages/celery/utils/collections.py", line 278, in __getitem__
return mapping[_key]
File "/usr/local/lib/python3.6/collections/__init__.py", line 987, in __getitem__
if key in self.data:
File "/usr/local/lib/python3.6/site-packages/kombu/utils/objects.py", line 44, in __get__
value = obj.__dict__[self.__name__] = self.__get(obj)
File "/usr/local/lib/python3.6/site-packages/celery/app/base.py", line 141, in data
return self.callback()
File "/usr/local/lib/python3.6/site-packages/celery/app/base.py", line 924, in _finalize_pending_conf
conf = self._conf = self._load_config()
File "/usr/local/lib/python3.6/site-packages/celery/app/base.py", line 934, in _load_config
self.loader.config_from_object(self._config_source)
File "/usr/local/lib/python3.6/site-packages/celery/loaders/base.py", line 131, in config_from_object
self._conf = force_mapping(obj)
File "/usr/local/lib/python3.6/site-packages/celery/utils/collections.py", line 46, in force_mapping
if isinstance(m, (LazyObject, LazySettings)):
File "/usr/local/lib/python3.6/site-packages/django/utils/functional.py", line 215, in inner
self._setup()
File "/usr/local/lib/python3.6/site-packages/django/conf/__init__.py", line 43, in _setup
self._wrapped = Settings(settings_module)
File "/usr/local/lib/python3.6/site-packages/django/conf/__init__.py", line 106, in __init__
mod = importlib.import_module(self.SETTINGS_MODULE)
File "/usr/local/lib/python3.6/importlib/__init__.py", line 126, in import_module
return _bootstrap._gcd_import(name[level:], package, level)
File "<frozen importlib._bootstrap>", line 994, in _gcd_import
File "<frozen importlib._bootstrap>", line 971, in _find_and_load
File "<frozen importlib._bootstrap>", line 955, in _find_and_load_unlocked
File "<frozen importlib._bootstrap>", line 665, in _load_unlocked
File "<frozen importlib._bootstrap_external>", line 678, in exec_module
File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
File "/app/spacenews/spacenews/settings.py", line 7, in <module>
class Base(Configuration):

celery.py

from __future__ import absolute_import
import os
from celery import Celery
# set the default Django settings module for the 'celery' program.
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'spacenews.settings')

app = Celery('spacenews')
# Using a string here means the worker will not have to
# pickle the object when using Windows.
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文件看起来对芹菜无效。通常设置文件如下所示:


DEBUG = True
BROKER_URL = 'redis://localhost:6379/'
CELERY_RESULT_BACKEND = 'redis://localhost:6379/'
#CELERYD_HIJACK_ROOT_LOGGER = False
# use json format for everything
CELERY_ACCEPT_CONTENT = ['application/json']
CELERY_TASK_SERIALIZER = 'json'
CELERY_RESULT_SERIALIZER = 'json'
CELERY_TIMEZONE = 'UTC'

CELERY_BEAT_SCHEDULE = {

'login_mb': {
'task': 'events.tasks.login_mb',
'schedule': timedelta(seconds=10),
} ,
'mb_get_events': {
'task': 'events.tasks.mb_get_events' ,
'schedule': timedelta(seconds=10) ,
} ,
}

而不使用像BaseProductionDev这样的对象。如果你想使用现有的对象,你必须做额外的工作,将这些对象作为django-settings对象上的设置公开(用于配置芹菜(。

或者,您可以向config_from_object提供包含该芹菜配置的类的实例。

最后,请注意,您的broker_url设置应该是BROKER_URL,而不是CELERY_BROKER_URL

最新更新