使用Browsershot生成PDF时Node权限拒绝问题排查
解决Laravel中Browsershot调用Node出现Permission denied错误
在Laravel项目中使用Browsershot生成PDF时,触发了Node的权限拒绝错误,具体报错信息和示例代码如下:
报错信息
The command "PATH=$PATH:/usr/local/bin:/opt/homebrew/bin NODE_PATH=`/home/quanph/.nvm/versions/node/v18.19.0/bin/node /home/quanph/.nvm/versions/node/v18.19.0/bin/npm root -g` /home/quanph/.nvm/versions/node/v18.19.0/bin/node '/var/www/html/api-service/vendor/spatie/browsershot/src/../bin/browser.cjs' '{"url":"file:///tmp/1184929759-0777396001705702182/index.html","action":"pdf","options":{"path":"invoice.pdf","args":[],"viewport":{"width":800,"height":600},"displayHeaderFooter":false,"format":"a4","printBackground":true}}'" failed. Exit Code: 126(Invoked command cannot execute) Working directory: /var/www/html/api-service/public Output: ================ Error Output: ================ sh: 1: /home/quanph/.nvm/versions/node/v18.19.0/bin/node: Permission denied sh: 1: /home/quanph/.nvm/versions/node/v18.19.0/bin/node: Permission denied
示例代码
Route::get('/test', function () { \Spatie\Browsershot\Browsershot::url('http://api.imta.edu/') ->setIncludePath('/home/quanph/.nvm/versions/node/v18.19.0/bin') ->save('invoice.pdf'); });
错误原因
- 运行Laravel的服务器进程用户(如
www-data、apache)没有权限访问通过nvm安装的Node二进制文件。 - nvm默认将Node安装在当前用户主目录下,目录权限仅对该用户开放,服务器进程用户无法读取或执行该路径下的Node文件。
解决方案
方案一:调整Node相关目录的权限
给其他用户添加Node文件及上级目录的执行和读取权限:
# 给Node二进制文件添加其他用户执行权限 chmod o+x /home/quanph/.nvm/versions/node/v18.19.0/bin/node # 给Node模块目录添加其他用户读和执行权限 chmod -R o+rx /home/quanph/.nvm/versions/node/v18.19.0/lib/node_modules # 确保上级目录都有访问权限 chmod o+x /home/quanph chmod o+x /home/quanph/.nvm chmod o+x /home/quanph/.nvm/versions chmod o+x /home/quanph/.nvm/versions/node chmod o+x /home/quanph/.nvm/versions/node/v18.19.0 chmod o+x /home/quanph/.nvm/versions/node/v18.19.0/bin
方案二:将服务器用户加入你的用户组
把运行Laravel的服务器用户(以www-data为例)添加到你的用户组quanph,使其拥有该组的权限:
usermod -aG quanph www-data
之后重启服务器服务(根据你使用的Web服务器选择):
# Apache systemctl restart apache2 # Nginx systemctl restart nginx
方案三:使用系统全局安装的Node
卸载nvm管理的Node,改用系统包管理器安装Node,这样Node会被安装到全局可访问的路径(如/usr/bin/node),服务器用户默认有权限访问:
# 卸载nvm中的Node版本 nvm uninstall v18.19.0 # Ubuntu/Debian系统安装Node apt update && apt install nodejs npm # CentOS/RHEL系统安装Node yum install nodejs npm
修改Browsershot代码,无需指定setIncludePath:
Route::get('/test', function () { \Spatie\Browsershot\Browsershot::url('http://api.imta.edu/') ->save('invoice.pdf'); });
方案四:创建软链接到全局目录
将nvm安装的Node链接到系统全局可访问的目录,无需修改现有安装:
ln -s /home/quanph/.nvm/versions/node/v18.19.0/bin/node /usr/local/bin/node ln -s /home/quanph/.nvm/versions/node/v18.19.0/bin/npm /usr/local/bin/npm
之后可以去掉代码中的setIncludePath,或者设置为/usr/local/bin。
内容的提问来源于stack exchange,提问作者quanph
相关产品推荐
相关产品推荐

