当部署用户与运行用户不同时,处理Ruby on Rails项目中的shared / tmp

时间:2014-05-27 09:48:28

标签: ruby-on-rails permissions capistrano

我的服务器上有两个用户,我自己管理的Ubuntu 12.04虚拟服务器:

  • projectx用于部署应用程序,是/ var / www / projectx
  • 中大多数文件的用户/组
  • projectx_rails,它用于运行Rails应用程序。这样,运行rails应用程序无法修改源代码。

某些目录(如公共/上传)被配置为属于projectx_rails:projectx_rails,因此rails应用程序可以编写上传的文件。

我的问题来到目录tmp。该目录位于/ var / www / projectx / shared中,并以通常的capistrano处理版本的方式链接到每个版本。问题是部署期间创建的某些文件无法由运行的rails应用程序写入,并且rails应用程序创建的文件不能被部署过程写入。

有办法解决这个问题吗?将那里的所有文件都归属于projectx_rails:projectx_rails并且可写组是足够好的,但我不确定如何触发它。

我正在使用:Capistrano 3,Rails 3.2,Ruby 2.1.2,Unicorn 4.8.3,nginx。

5 个答案:

答案 0 :(得分:4)

嗯,这是我的理论。显然很难对我进行测试,所以请考虑猜测。

首先:制作两个用户所属的群组。与projectx_shared一样。

第二:使该群组成为tmp目录的群组所有者:

chown projectx_rails:projectx_shared tmp

第三:在此目录中设置 setgid 位:

chmod g+s tmp

现在,添加到tmp的文件的群组所有者应自动设置为projectx_shared。我认为这也适用于capistrano任务。

我假设您在部署时,文件已自动获得rw-rw-r--权限。如果没有,您需要将UMASK设置为002,例如: .bashrc也是如此。

让我知道它是否有效......

答案 1 :(得分:2)

可能对共享文件使用ACL吗?唯一能够在fstab中启用ACL支持。

setfacl -m d:u:projectx:rwx,u:projectx:rwx,\
d:u:projectx_rails:rwx,u:projectx_rails:rwx /var/www/projectx/shared/tmp

答案 2 :(得分:1)

您可以通过capistrano在远程计算机上运行命令。您可以在对应用程序进行符号链接之后运行目录所有者更改。

deploy.rb文件中,为其添加回调:

after 'deploy:create_symlink' do
  run "chown -R projectx_rails:projectx_rails #{current_release}/tmp"
end

答案 3 :(得分:1)

我目前的解决方案是完成这项任务:

namespace :deploy do
  desc "Fix permissions"
  task :fix_permissions do
    on roles(:app) do
      execute "sudo chown -R projectx_rails:projectx_rails #{shared_path}/tmp"
      execute "sudo chmod ug+rwX,o+rw #{shared_path}/tmp"
    end
  end
end

并在部署的开始和结束时运行它:

after "deploy:started", "deploy:fix_permissions"
before "deploy:restart", "deploy:fix_permissions"

为了让它成功,我必须将它添加到我的sudoers:

projectx ALL=NOPASSWD: /bin/chown -R projectx_rails\:projectx_rails /var/www/projectx/shared/tmp
projectx ALL=NOPASSWD: /bin/chmod ug+rwX\,o+rw /var/www/projectx/shared/tmp

让我感到很不舒服。

答案 4 :(得分:1)

1)确保projectx和projectx_rails都是组projectx的成员 2)将其添加到部署:

task :change_tmp_pems do
   run "chmod -Rf 775 #{shared_path}/tmp"
end
after "deploy:started", :change_tmp_pems

-f将默默地失败/跳过它无权访问的任何文件,因此不会成为问题。

4行代码,非常简洁。 不要与chown混乱,因为它通常需要sudo并且是不必要的。