在cookiecutter-django项目中使用Celery遇运行异常求助
Hey there, let's work through this Celery issue with your cookiecutter-django project—since you've got all the core services (Django, PostgreSQL, Redis) running in Docker, we can narrow down the common fixes step by step.
Even if you think all containers are up, it's worth verifying the Celery worker/beat containers specifically:
- Run
docker-compose psand look for entries likeceleryworkerorcelerybeat—make sure their state isUp. - If they're running, pull the logs to spot errors:
Common red flags here include missing environment variables (like the Redis connection URL), permission issues accessing task files, or import errors in your task modules.docker-compose logs celeryworker
Celery relies on Redis to queue tasks, so let's confirm the connection is solid:
- In your Django settings (usually
config/settings/local.pyorproduction.py), check thatCELERY_BROKER_URLandCELERY_RESULT_BACKENDpoint to your Redis container—something likeredis://redis:6379/0(assuming your Redis service is namedredisindocker-compose.yml). - Test the connection directly from the Celery container:
You should get adocker-compose exec celeryworker redis-cli -h redis pingPONGresponse. If not, there's a network issue between the Celery and Redis containers (double-check yourdocker-compose.ymlnetwork config).
Cookiecutter-django uses a dedicated Celery app instance, so make sure your tasks are hooked into it:
- Import the shared task decorator from the project's Celery app, not the default Celery module:
from config.celery_app import app as celery_app @celery_app.task def my_sample_task(): # Your task logic here - Confirm Celery can discover your tasks: Cookiecutter-django usually enables auto-discovery for
tasks.pyfiles in apps listed inINSTALLED_APPS. If your task is in a non-standard location, add the module path toCELERY_IMPORTSin your settings. - Remember to restart the Celery worker after adding new tasks—workers don't auto-reload tasks by default (you can enable autoreload for development with
--autoreload, but it's not recommended for production).
It's easy to accidentally run tasks synchronously instead of sending them to the queue:
- Always use
.delay()or.apply_async()to trigger async tasks. Callingmy_sample_task()directly runs it in the Django process, not through Celery. - Example of correct invocation:
# This sends the task to the queue my_sample_task.delay()
If tasks are being sent but not processed, check if they're piling up in Redis:
- Connect to the Redis container:
docker-compose exec redis redis-cli - List all Celery-related keys:
KEYS *celery* - Check the default queue for pending tasks:
If tasks are here but not being processed, confirm your worker is listening to the right queue. The worker command inLRANGE celery 0 -1docker-compose.ymlshould look like this (it defaults to theceleryqueue):
If you're using a custom queue, make sure the worker is started withcelery -A config.celery_app worker -l info-Q your_queue_name.
If all the above checks pass, look for more subtle issues:
- Cookiecutter-django uses JSON serialization by default. If your task arguments include non-serializable objects (like model instances without a pk, or custom classes), the task will fail silently. Pass primitive types (like IDs) instead, or use a different serializer if needed.
- Ensure the timezone setting (
TIME_ZONEin Django settings) matches between Django and Celery—mismatches can cause task scheduling issues (especially for periodic tasks with Celery Beat).
内容的提问来源于stack exchange,提问作者JanMensch

