Rails 4项目中wicked_pdf访问tmp目录的权限配置问题
解决WickedPDF生成PDF时的tmp/cache权限拒绝问题
问题根源
你遇到的核心问题是预编译资产时使用了root用户,导致tmp目录(包括子目录cache)被root创建/覆盖,而Passenger运行的Rails进程是以www-data用户身份执行的,没有权限写入root所有的目录。直接改一次所有者没用,因为每次预编译都会被root重新生成目录,覆盖之前的权限设置。
分步解决方案
1. 使用正确用户执行资产预编译
不要用root用户运行资产预编译,改用www-data用户(Passenger的运行用户)执行:
sudo -u www-data bundle exec rake assets:precompile RAILS_ENV=production
这样生成的tmp目录及其子目录的所有者就是www-data,Rails进程自然有读写权限。
如果你的项目使用专门的部署用户(比如deploy),可以确保deploy用户和www-data同组,然后预编译后调整组权限:
bundle exec rake assets:precompile RAILS_ENV=production sudo chown -R deploy:www-data /path/to/your/app/tmp
2. 持久化tmp目录的权限设置
为了避免后续操作意外改变权限,设置tmp目录的组权限继承,确保新创建的文件/目录自动属于www-data组并具备读写权限:
# 修改tmp目录的所有者和组 sudo chown -R www-data:www-data /path/to/your/app/tmp # 给组添加读写权限 sudo chmod -R g+rw /path/to/your/app/tmp # 设置setgid位,让新创建的子目录继承父目录的组 sudo find /path/to/your/app/tmp -type d -exec chmod g+s {} \;
3. (可选)指定WickedPDF专属缓存目录
如果不想依赖默认的tmp/cache,可以自定义WickedPDF的缓存路径,避免和其他组件的缓存目录冲突:
在config/initializers/wicked_pdf.rb中添加配置:
WickedPdf.config = { cache_path: Rails.root.join('tmp', 'wicked_pdf_cache').to_s }
然后创建该目录并设置正确权限:
sudo mkdir -p /path/to/your/app/tmp/wicked_pdf_cache sudo chown www-data:www-data /path/to/your/app/tmp/wicked_pdf_cache sudo chmod 750 /path/to/your/app/tmp/wicked_pdf_cache
4. 重启服务生效
最后重启Passenger和Nginx,确保权限和配置变更生效:
sudo passenger-config restart-app /path/to/your/app sudo service nginx restart
验证方法
可以通过以下命令确认权限是否正确:
# 查看tmp/cache的所有者和权限 ls -ld /path/to/your/app/tmp/cache # 查看Passenger运行的用户 ps aux | grep passenger
如果tmp/cache的所有者是www-data,且Passenger进程用户也是www-data,问题就解决了。
内容的提问来源于stack exchange,提问作者damuz91
相关产品推荐
相关产品推荐

