Celery守护进程运行时出现“No such file or directory”错误原因排查
从你的错误堆栈信息来看,问题出在守护进程模式下Celery无法找到wkhtmltopdf可执行文件,而非你的代码逻辑本身——毕竟前台启动Celery时一切正常。
核心原因
当你用celery multi start以守护进程模式启动时,Celery不会加载当前用户的Shell环境变量(比如~/.bashrc或~/.profile里配置的PATH)。而wkhtmltopdf的安装目录可能不在守护进程默认的PATH中,导致Python的subprocess模块调用它时抛出OSError: No such file or directory。
解决方案
方案1:在代码中指定wkhtmltopdf的绝对路径
这是最直接的解决方法。首先通过终端命令找到wkhtmltopdf的绝对路径:
which wkhtmltopdf
假设输出是/usr/local/bin/wkhtmltopdf,然后修改你代码中PDFTemplateResponse的cmd_options,添加wkhtmltopdf参数指定绝对路径:
response = PDFTemplateResponse( request=request, template=template, filename=filename, context=context, show_content_in_browser=True, cmd_options={ 'margin-top': 10, 'zoom': 1, 'viewport-size': '1366 x 513', 'javascript-delay': 1000, 'no-stop-slow-scripts': True, 'wkhtmltopdf': '/usr/local/bin/wkhtmltopdf' # 替换为你的实际路径 }, )
方案2:启动Celery时指定完整的PATH环境变量
如果你不想修改代码,可以在启动Celery守护进程时显式设置PATH,把wkhtmltopdf所在目录包含进去:
celery multi start worker -A erp -l info --env PATH=/usr/local/bin:/usr/bin:/bin
注意把/usr/local/bin替换为你实际的wkhtmltopdf所在目录。
方案3:修改Celery启动脚本的环境变量
如果是用系统服务(比如systemd)管理Celery守护进程,可以在服务配置文件中添加Environment=PATH=/usr/local/bin:/usr/bin:/bin,确保守护进程能找到wkhtmltopdf。
验证方法
修改后重启Celery守护进程,触发生成PDF的任务,应该就能正常执行了。如果还是报错,可以检查:
- wkhtmltopdf的绝对路径是否正确
- Celery守护进程是否有访问该可执行文件的权限
内容的提问来源于stack exchange,提问作者MiniGunnR

