Systemd启动Celery守护进程报CHDIR失败、模块找不到问题排查
问题根因
你遇到的两个报错都是配置疏漏导致的,核心问题如下:
- 第一个CHDIR报错是路径拼写低级错误:你在service文件里写的
WorkingDirectory=/home/ec2-usuer/DjangoProjects/myproj把用户名ec2-user错拼成了ec2-usuer(多打了一个u),这个路径根本不存在,systemd启动时要切换工作目录直接失败。 - 删掉WorkingDirectory后报模块找不到是必然结果:Celery启动时需要把项目根目录加入Python的模块搜索路径,没有WorkingDirectory时systemd默认工作目录是系统根目录
/,Python自然搜不到你的myproj项目包。
除了这两个直接触发报错的问题,还有3个隐藏的配置坑,就算改了拼写也会启动失败:
- 权限不匹配:服务配置的运行用户是
apache,但项目放在ec2-user的家目录下,Linux默认用户家目录权限是700(仅所有者可读可写可进入),apache用户根本没有权限访问这个目录下的文件。 - 环境文件语法错误:你在
/etc/conf.d/celery里用了shell的export语法定义变量,systemd的EnvironmentFile不识别shell语法,这么写会导致变量无法正常读取;另外你写的CELERYD_CHDIR配置只在官方提供的init.d脚本里生效,用systemd部署时这个参数完全没用,工作目录必须靠systemd的WorkingDirectory指定。 - PATH缺失:你没有把Celery对应的Python解释器目录加入系统PATH,启动时可能出现找不到依赖库、找不到Python命令的问题。
修正方案
按以下步骤调整配置即可正常启动:
- 修正
/etc/systemd/system/celery.service的Service段配置,改对路径拼写、补全PATH:
[Service] Type=forking User=apache Group=apache Environment=PATH=/opt/python39/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin EnvironmentFile=/etc/conf.d/celery WorkingDirectory=/home/ec2-user/DjangoProjects/myproj ExecStart=/bin/sh -c '${CELERY_BIN} -A $CELERY_APP multi start $CELERYD_NODES \ --pidfile=${CELERYD_PID_FILE} --logfile=${CELERYD_LOG_FILE} \ --loglevel="${CELERYD_LOG_LEVEL}" $CELERYD_OPTS' ExecStop=/bin/sh -c '${CELERY_BIN} multi stopwait $CELERYD_NODES \ --pidfile=${CELERYD_PID_FILE} --logfile=${CELERYD_LOG_FILE} \ --loglevel="${CELERYD_LOG_LEVEL}"' ExecReload=/bin/sh -c '${CELERY_BIN} -A $CELERY_APP multi restart $CELERYD_NODES \ --pidfile=${CELERYD_PID_FILE} --logfile=${CELERYD_LOG_FILE} \ --loglevel="${CELERYD_LOG_LEVEL}" $CELERYD_OPTS' Restart=always
- 修正
/etc/conf.d/celery配置,删掉无效的export和CELERYD_CHDIR,直接写键值对:
CELERYD_NODES="w1 w2 w3" CELERY_BIN="/opt/python39/bin/celery" CELERY_APP="myproj.celery_tasks" CELERYD_OPTS="--time-limit=300 --concurrency=8" CELERYD_PID_FILE="/var/run/celery/%n.pid" CELERYD_LOG_FILE="/var/log/celery/%n%I.log" CELERYD_LOG_LEVEL="INFO" CELERYBEAT_PID_FILE="/var/run/celery/beat.pid" CELERYBEAT_LOG_FILE="/var/log/celery/beat.log" DJANGO_SETTINGS_MODULE="myproj.settings"
- 修复目录权限:
- 递归给
/var/run/celery、/var/log/celery设置apache用户的读写执行权限 - 递归给项目目录
/home/ec2-user/DjangoProjects/myproj设置apache用户的读+执行权限,项目中需要写入的目录(比如静态文件目录、上传目录、日志目录)额外加写权限
- 递归给
- 重新加载systemd配置启动服务:
systemctl daemon-reload systemctl restart celery # 查看启动状态 systemctl status celery
如果你后续改用Python虚拟环境部署,只需要把
CELERY_BIN和PATH里的Python路径替换成虚拟环境下的对应路径即可,不要混用系统Python和虚拟环境的依赖包。
内容的提问来源于stack exchange,提问作者Shmack
相关产品推荐
相关产品推荐

