Docker Compose+Django+Celery下'Module my_project无celery属性'错误排查
运行docker compose up时Celery容器报错,错误信息如下:
| Usage: celery [OPTIONS] COMMAND [ARGS]... |
|---|
| Try 'celery --help' for help. |
| Error: Invalid value for '-A' / '--app': |
| Unable to load celery application. |
| Module 'my_project' has no attribute 'celery' |
celeryworker exited with code 2
环境版本:
- Docker version 20.10.23, build 7155243
- Django 4.1.7
- Python 3.11
- Celery 5.2.7
相关配置文件:
Dockerfile
FROM python:3.11.0 # Set environment variables ENV PYTHONDONTWRITEBYTECODE=1 ENV PYTHONUNBUFFERED=1 # Set work directory WORKDIR /code # Install dependencies RUN pip install --upgrade pip COPY requirements.txt /code/ RUN pip install -r requirements.txt # Copy the Django project COPY . /code/
docker-compose.yml
services: db: image: postgres:15.2 restart: always volumes: - ./data/db:/var/lib/postgresql/data environment: - POSTGRES_DB=postgres - POSTGRES_USER=postgres - POSTGRES_PASSWORD=postgres cache: image: redis:7.0.10 restart: always volumes: - ./data/cache:/data rabbit: image: rabbitmq:3.11.8 restart: always ports: - 5673:5673 - 15672:15672 - 25672:25672 #? volumes: - ./data/rabbit/data:/var/lib/rabbitmq - ./data/rabbit/log:/var/log/rabbitmq web: build: . command: ["./wait-for-it.sh", "db:5432", "--", "uwsgi","--ini", "/code/config/uwsgi/uwsgi.ini"] restart: always volumes: - .:/code environment: - DJANGO_SETINGS_MODULE=my_project.settings.production - POSTGRES_BD=postgres - POSTGRES_USER=postgres - POSTGRES_PASSWORD=postgres depends_on: - db - cache nginx: image: nginx:1.23.1 restart: always volumes: - ./config/nginx:/etc/nginx/templates - .:/code ports: - "80:80" - "443:443" daphne: build: . working_dir: /code/my_project/ command: ["../wait-for-it.sh", "db:5432", "--", "daphne", "-u", "/code/my_project/daphne.sock", "my_project.asgi:application"] restart: always volumes: - .:/code environment: - DJANGO_SETTINGS_MODULE=my_project.settings.production - POSTGRES_DB=postgres - POSTGRES_USER=postgres - POSTGRES_PASSWORD=postgres depends_on: - db - cache celeryworker: container_name: celeryworker build: . volumes: - .:/code #command: python -m celery -A my_project.celery worker -l info #command: ["./wait-for-it.sh", "rabbit:5673", "--", "celery", "-A","my_project.celery","worker","-l","info"] #"python","-m", command: ["./wait-for-it.sh", "web:8000", "--", "celery", "-A","my_project","worker","-l","info"] #"python","-m", depends_on: - rabbit - web
my_project/celery.py
import os from celery import Celery os.environ.setdefault("DJANGO_SETTINGS_MODULE", "my_project.settings.production") app = Celery("my_project") app.config_from_object("django.conf:settings", namespace="CELERY") app.autodiscover_tasks()
my_project/settings/production.py(节选)
CELERY_BROKER_URL = 'amqp://rabbit:5672'
my_project/init.py
from my_project.celery import app as celery_app __all__ = ("celery_app",)
已尝试操作:
- 修改docker-compose.yml中的Celery启动命令
- 调整配置参数
- 启用/禁用wait-for-it脚本
- 参考相关解决方案
本地未使用Docker时,运行Celery worker完全正常。
将docker-compose中的命令改为my_project.my_project.celery_app或my_project.my_project,错误变为ModuleNotFoundError: No module named 'my_project.settings'。
改用celeryconfig.py代替从Django settings加载配置(去掉os.environ.setdefault和app.config_from_object("django.conf:settings"...),Celery容器能启动但无任务注册,怀疑Docker读取文件层级存在问题。
1. 检查Python路径与工作目录
Docker容器的工作目录为/code,需确认该路径是否在Python的sys.path中。可在Celery启动命令前添加调试步骤验证:
command: ["./wait-for-it.sh", "web:8000", "--", "bash", "-c", "python -c 'import sys; print(sys.path)' && celery -A my_project worker -l info"]
如果/code不在输出结果中,需将其加入Python路径,比如在启动命令前设置export PYTHONPATH=/code。
2. 修正环境变量拼写错误
注意到web服务的环境变量中DJANGO_SETINGS_MODULE少写了一个t(正确应为DJANGO_SETTINGS_MODULE),虽然Celery配置中手动设置了该变量,但统一环境变量可避免潜在问题,建议修正:
# web服务环境变量 - DJANGO_SETTINGS_MODULE=my_project.settings.production
3. 明确Celery app指向
项目结构中my_project/__init__.py已导出celery_app,因此Celery启动命令可直接指定my_project.celery_app:
command: ["./wait-for-it.sh", "rabbit:5672", "--", "celery", "-A", "my_project.celery_app", "worker", "-l", "info"]
同时注意RabbitMQ端口不匹配问题:Celery配置使用的是5672,但docker-compose中rabbit的端口映射为5673:5673,需二选一修正:
- 将
CELERY_BROKER_URL改为amqp://rabbit:5673 - 将rabbit的端口映射改为
5672:5672
4. 确认项目结构正确性
确保容器内/code下的目录结构符合预期:
/code ├── my_project │ ├── __init__.py │ ├── celery.py │ ├── settings │ │ ├── production.py │ │ └── ... │ └── ... ├── Dockerfile ├── docker-compose.yml └── ...
若my_project存在嵌套情况,会导致模块导入错误。
5. 调试模块导入问题
进入容器手动执行命令排查:
docker exec -it celeryworker bash # 进入容器后执行 cd /code python -c "import my_project; print(dir(my_project))"
查看输出中是否包含celery_app,若没有,说明__init__.py未被正确加载或文件权限存在问题(比如容器内文件为root权限,Python无法读取)。可检查文件权限:
ls -l /code/my_project/
若权限异常,可在Dockerfile中添加:
RUN chown -R www-data:www-data /code
或根据实际运行用户调整权限。
内容的提问来源于stack exchange,提问作者a.jones

