Celery定时任务在DigitalOcean Ubuntu服务器未注册报错求助
Let's walk through why your send_email_task is throwing this KeyError('periodic_tasks.send_email_task',) error on your DO server, even though it works locally. Here are the most likely fixes to try:
1. Fix the Empty Broker Configuration (Critical!)
First off, your Celery app is initialized with an empty broker string:
app = Celery('periodic_tasks', broker='')
Local environments might fall back to a default (like a local Redis/RabbitMQ instance you have running without thinking), but production servers won't. A missing broker prevents Celery from properly registering and routing tasks.
Fix:
Replace the empty string with a valid broker URL (e.g., Redis or RabbitMQ). For example, if using Redis:
app = Celery('periodic_tasks', broker='redis://localhost:6379/0')
Make sure the broker service is installed and running on your DO server too (e.g., sudo systemctl start redis-server).
2. Ensure Supervisord Runs the Worker from the Correct Directory
If your periodic_tasks.py isn't in the working directory where supervisord starts the Celery process, the worker won't find the task module.
Fix:
Add the directory directive to your supervisord config for the Celery process, pointing to the folder containing periodic_tasks.py:
[program:celery-worker] command=/path/to/your/venv/bin/celery -A periodic_tasks worker -B --loglevel=info directory=/path/to/your/project/folder user=your-ubuntu-user autostart=true autorestart=true stdout_logfile=/var/log/celery/celery.log stderr_logfile=/var/log/celery/celery.err
Also, note that using the full path to your virtual environment's Celery executable avoids conflicts with system-wide Celery installations.
3. Verify the Worker Actually Loads Your Task
When the Celery worker starts, it logs a section like [tasks] that lists all registered tasks. Check your Celery logs (configured in supervisord above) — if periodic_tasks.send_email_task isn't listed there, the worker isn't loading the module.
Fixes:
- Add your project path to Python's
sys.pathif it's not already there. You can do this inperiodic_tasks.py:import sys from pathlib import Path # Add the project root to Python's module search path sys.path.append(str(Path(__file__).parent.resolve())) - Or prepend the
PYTHONPATHto your supervisord command:command=PYTHONPATH=/path/to/your/project/folder /path/to/venv/bin/celery -A periodic_tasks worker -B --loglevel=info
4. Check for Case Sensitivity and Typos
Linux filesystems are case-sensitive. Double-check that:
- Your file is named exactly
periodic_tasks.py(notPeriodicTasks.pyorperiodic-tasks.py) - The task name in
beat_schedule("periodic_tasks.send_email_task") matches the actual task's fully qualified name.
5. Test Separating Beat and Worker Processes
Running Beat and Worker together with the -B flag can sometimes cause path or configuration conflicts. Try starting them separately to isolate the issue:
- Stop the supervisord Celery process first.
- Start the worker:
cd /path/to/your/project && /path/to/venv/bin/celery -A periodic_tasks worker --loglevel=info - In a separate terminal, start Beat:
cd /path/to/your/project && /path/to/venv/bin/celery -A periodic_tasks beat --loglevel=info
If this works, update your supervisord config to run two separate processes (one for worker, one for beat).
内容的提问来源于stack exchange,提问作者Konstantin Rusanov

