You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 22:29:55