部署含Celery任务的DRF至Docker时遇Celery导入错误
Docker部署DRF+Celery出现循环导入错误的解决方案
你怀疑的没错,问题核心就是Dockerfile中把应用目录下的celery.py复制到了容器的/app根目录。Python模块导入优先级里,当前工作目录(/app)会优先于site-packages中的第三方库,所以代码执行from celery import Celery时,会先加载/app/celery.py而非真正的Celery库,直接引发循环导入错误。
1. 修正Dockerfile
直接删除Dockerfile中这一行多余的复制命令:
COPY ./file_upload_service/celery.py /app/
后续的COPY . /app/已经会把整个项目目录(包括file_upload_service/celery.py)复制到容器中,提前复制到根目录纯属画蛇添足。
修正后的完整Dockerfile:
# Use an official Python runtime as a parent image FROM python:3.10-alpine # Set the working directory to /app WORKDIR /app # Copy the requirements file into the container at /app COPY requirements.txt /app/ # Set the environment variable for the Celery command ENV C_FORCE_ROOT=1 # Install any needed packages specified in requirements.txt RUN pip install --no-cache-dir -r requirements.txt # Copy the entire application directory into the container at /app COPY . /app/ # Expose port 8000 EXPOSE 8000 # Define environment variables ENV DJANGO_SETTINGS_MODULE=file_upload_service.settings # Start the server CMD ["python3", "manage.py", "runserver", "0.0.0.0:8000"]
2. 优化celery.py配置(可选)
你的celery.py存在重复设置环境变量的问题,可以简化为:
import os from celery import Celery import django # 仅需一次设置环境变量 os.environ.setdefault("DJANGO_SETTINGS_MODULE", "file_upload_service.settings") django.setup() app = Celery("file_upload_service") app.config_from_object("django.conf:settings", namespace="CELERY") app.autodiscover_tasks()
3. 修正docker-compose.yml路径与端口问题
注意docker-compose中volumes路径与Dockerfile工作目录不一致,同时Celery连接Redis时需用容器内部端口:
version: "3.9" services: web: build: . command: python3 manage.py runserver 0.0.0.0:8000 volumes: - .:/app # 与Dockerfile工作目录统一为/app ports: - "8000:8000" depends_on: - db - redis - celery db: image: postgres environment: POSTGRES_DB: file_upload_service POSTGRES_USER: postgres POSTGRES_PASSWORD: postgres volumes: - "./db:/var/lib/postgresql/data" ports: - "5433:5432" redis: image: "redis" ports: - "6380:6379" celery: build: . command: celery -A file_upload_service worker -l info volumes: - .:/app # 同样统一路径为/app depends_on: - db - redis environment: - DJANGO_SETTINGS_MODULE=file_upload_service.settings - CELERY_BROKER_URL=redis://redis:6379 # 容器内部通信用Redis默认端口6379,而非宿主机映射的6380 - CELERY_RESULT_BACKEND=redis://redis:6379
最后执行步骤
- 清理旧镜像与容器:
docker-compose down --rmi all - 重新构建并启动服务:
docker-compose up --build
内容的提问来源于stack exchange,提问作者John Mboga
相关产品推荐
相关产品推荐

