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 .
# ...
Вернуться на верх