ModuleNotFoundError при запуске celery в проекте Django
У меня структура проекта Django выглядит следующим образом (не показываю все файлы/папки):
myproj/
├── __init__.py
├── config/
│ ├── __init__.py <-- imports `celery_app` as per docs
│ ├── settings/
│ │ ├── __init__.py
│ │ └── base.py
│ ├── celery.py <-- defines `app = Celery("myproj")`
│ └── wsgi.py
├── myapp1/
└── myapp2/
У меня есть docker-compose.yml
, который устанавливает веб- и рабочие службы, и рабочая служба представляет собой что-то вроде:
worker:
build:
context: "."
target: "app"
command: celery -A config worker -l info
entrypoint: []
Но что бы я ни пробовал для -A
при запуске celery, я получаю ModuleNotFound. Я пробовал config
, myproj.config
и myproj
. Я пробовал добавлять --workdir=/path/to/myproj
, но безрезультатно.
UPDATE С помощью -A config
я получаю следующее:
oohdir-worker-1 | Usage: celery [OPTIONS] COMMAND [ARGS]...
oohdir-worker-1 | Try 'celery --help' for help.
oohdir-worker-1 |
oohdir-worker-1 | Error: Invalid value for '-A' / '--app':
oohdir-worker-1 | Unable to load celery application.
oohdir-worker-1 | The module config was not found.
oohdir-worker-1 exited with code 2
Но с -A myproj.config
я получаю следующее:
myproj-worker-1 | Usage: celery [OPTIONS] COMMAND [ARGS]...
myproj-worker-1 | Try 'celery --help' for help.
myproj-worker-1 |
myproj-worker-1 | Error: Invalid value for '-A' / '--app':
myproj-worker-1 | Unable to load celery application.
myproj-worker-1 | While trying to load the module myproj.config the following error occurred:
myproj-worker-1 | Traceback (most recent call last):
myproj-worker-1 | File "/home/python/.local/lib/python3.10/site-packages/celery/bin/celery.py", line 57, in convert
myproj-worker-1 | return find_app(value)
myproj-worker-1 | File "/home/python/.local/lib/python3.10/site-packages/celery/app/utils.py", line 384, in find_app
myproj-worker-1 | sym = symbol_by_name(app, imp=imp)
myproj-worker-1 | File "/home/python/.local/lib/python3.10/site-packages/kombu/utils/imports.py", line 56, in symbol_by_name
myproj-worker-1 | module = imp(module_name, package=package, **kwargs)
myproj-worker-1 | File "/home/python/.local/lib/python3.10/site-packages/celery/utils/imports.py", line 105, in import_from_cwd
myproj-worker-1 | return imp(module, package=package)
myproj-worker-1 | File "/usr/local/lib/python3.10/importlib/__init__.py", line 126, in import_module
myproj-worker-1 | return _bootstrap._gcd_import(name[level:], package, level)
myproj-worker-1 | File "<frozen importlib._bootstrap>", line 1050, in _gcd_import
myproj-worker-1 | File "<frozen importlib._bootstrap>", line 1027, in _find_and_load
myproj-worker-1 | File "<frozen importlib._bootstrap>", line 1004, in _find_and_load_unlocked
myproj-worker-1 | ModuleNotFoundError: No module named 'myproj'
myproj-worker-1 |
myproj-worker-1 exited with code 2
При вызове celery
вам необходимо убедиться, что файлы вашего проекта находятся в рабочем каталоге. В случае с вашим Dockerfile это обычно означает установку вашего WORKDIR
в то же место, куда вы копируете файлы проекта. Например:
#...
WORKDIR /app
COPY . /app
# ...
CMD ["celery", "-A", "myproj.config", "-l", "info"]
Другой способ убедиться, что это всегда работает правильно, - создать setup.py
для вашего проекта django и установить его с помощью pip (вместо копирования файлов проекта). Таким образом, ваше приложение и worker смогут быть вызваны независимо от рабочего каталога, потому что они будут импортированы из site-packages.
Пример этого с использованием многоэтапной сборки докеров:
FROM python:3.9-slim as build
WORKDIR /build
RUN pip install wheel
COPY requirements.txt .
# create wheels for your dependencies
RUN python -m pip wheel -w /build/dist -r requirements.txt
# build your project to a wheel too
COPY . .
RUN pip wheel --no-deps --find-links /build/dist -w /build/dist .
FROM python:3.9-slim as app
COPY --from=build /build/dist /wheelhouse
# install your project (using the name in setup.py)
WORKDIR /app
RUN pip install --no-index --find-links /wheelhouse my-project
# you only need to copy manage.py here since your project is in site-packages
COPY manage.py .
# ...