【问题标题】:Capifony and directory ownersCapifony 和目录所有者
【发布时间】:2012-01-03 20:36:47
【问题描述】:

当我cap deploy 我的 Symfony2 项目时,然后登录到我的服务器,我看到 dev (app_dev.php) 运行正常,但 prod 版本 (app.php) 没有。

错误是

[Tue Jan 03 14:31:48 2012] [error] [client xxx.xxx.xxx.xxx] PHP Fatal error:  Uncaught exception 'RuntimeException' with message 'Failed to write cache file "/var/www/example/prod/releases/20120103202539/app/cache/prod/classes.php".' in /var/www/example/prod/releases/20120103202539/app/bootstrap.php.cache:1079\nStack trace:\n#0 /var/www/example/prod/releases/20120103202539/app/bootstrap.php.cache(1017): Symfony\\Component\\ClassLoader\\ClassCollectionLoader::writeCacheFile('/var/www/example/p...', '<?php  ????name...')\n#1 /var/www/example/prod/releases/20120103202539/app/bootstrap.php.cache(682): Symfony\\Component\\ClassLoader\\ClassCollectionLoader::load(Array, '/var/www/example/p...', 'classes', false, false, '.php')\n#2 /var/www/example/prod/releases/20120103202539/web/app.php(10): Symfony\\Component\\HttpKernel\\Kernel->loadClassCache()\n#3 {main}\n  thrown in /var/www/example/prod/releases/20120103202539/app/bootstrap.php.cache on line 1079

查看我看到的最近部署的缓存目录:

drwxrwxrwx 4 root     root     4096 Jan  3 14:28 .
drwxrwxr-x 5 root     root     4096 Jan  3 14:28 ..
drwxr-xr-x 6 www-data www-data 4096 Jan  3 14:28 dev
drwxrwxr-x 7 root     root     4096 Jan  3 14:28 prod

我可以用chown -R www-data.www-data prod/ 解决这个问题,但我想知道我是否可以从一开始就阻止这种情况发生?为什么目录有不同的所有者?

【问题讨论】:

    标签: deployment symfony capistrano capifony


    【解决方案1】:

    发生这种情况是因为您的网络服务器由用户运行,该用户无法写入刚刚创建的 cache/prod 目录。

    我知道并使用了两种解决方案。首先,添加额外的命令以在部署到Capfile 后运行。 Capfile 会这样:

    load 'deploy' if respond_to?(:namespace) # cap2 differentiator
    Dir['vendor/bundles/*/*/recipes/*.rb'].each { |bundle| load(bundle) }
    load Gem.find_files('symfony2.rb').last.to_s
    
    after "deploy:finalize_update" do
      run "sudo chown -R www-data:www-data #{latest_release}/#{cache_path}"
      run "sudo chown -R www-data:www-data #{latest_release}/#{log_path}"
      run "sudo chmod -R 777 #{latest_release}/#{cache_path}"
    end
    
    load 'app/config/deploy'
    

    第二种解决方案更优雅。您指定正确的user,谁可以在deploy.rb 中写信给cache,并确保您不使用sudo:

    set :user, "anton"
    set :use_sudo, false
    

    【讨论】:

    • 谢谢,听起来像我需要的。我不明白为什么 dev 目录归 www-data 所有。 Capifony 在服务器上以 root 用户身份运行,所以我猜 php 正在尝试创建缓存文件(而不是 root 用户)?
    • cache/dev 目录是由运行 CLI 版本的 php 创建的,该用户与运行 Web 服务器的用户不同。 cache/prod 正在运行,因为它将由 Web 服务器运行。我是这样理解的:)
    • 我明白你的意思,尽管看看 dir 所有者,我会说 /prod 由 root 拥有,而 /dev 由 www-data 拥有?
    【解决方案2】:

    在 capifony 的最新版本中,他们添加了设置可写目录的选项。 这是官方文章,解释了我在下面写的内容:http://capifony.org/cookbook/set-permissions.html

    您必须使用 sudo 进行部署(这不是一个好习惯,但它可以完成工作)

    set   :use_sudo,      false
    # To prompt the sudo password
    default_run_options[:pty] = true
    

    并告诉 capifony 哪些文件使缓存和日志文件夹可写:

    set :writable_dirs,     ["app/cache", "app/logs"]
    set :webserver_user,    "www-data"
    set :permission_method, :acl
    

    (你必须在你的机器上安装 acl,或者使用 :chwon 代替 :acl)

    编辑: 我刚刚意识到这还不够,“set_permissions”任务不会自动调用,所以你必须显式运行

    cap deploy:set_permissions
    

    或者在你的 deploy.rb 中添加这一行:

    before "deploy:restart", "deploy:set_permissions"
    

    【讨论】:

    • 您也可以在 deploy.rb 中添加 set :use_set_permissions, true 而不是 before "deploy:restart", "deploy:set_permissions"
    【解决方案3】:

    我通过将缓存文件夹添加到共享文件夹解决了这个问题。

    set :shared_children,     [app_path + "/cache", app_path + "/logs", web_path + "/uploads", "vendor"]
    

    这样部署时不会每次都重新创建目录,所以权限没有问题。

    【讨论】:

    • 回滚时可能会遇到问题。确保在角色返回时也清除缓存。哦,当你尝试清除缓存时,你又遇到了同样的问题,你没有权限删除服务器创建的文件。
    【解决方案4】:

    是的,不需要每次部署后都重新创建缓存,这种方案合乎逻辑且实用。

    Anton 的第二个解决方案 - 如果您在开发环境中缓存文件夹权限为 true,则可行

    【讨论】:

      猜你喜欢
      • 2022-09-28
      • 2020-01-27
      • 1970-01-01
      • 2016-07-04
      • 1970-01-01
      • 2018-12-31
      • 1970-01-01
      • 2013-12-02
      • 1970-01-01
      相关资源
      最近更新 更多