Capistrano 3 在目录中执行

Posted

技术标签:

【中文标题】Capistrano 3 在目录中执行【英文标题】:Capistrano 3 execute within a directory 【发布时间】:2013-10-27 11:50:21 【问题描述】:

我正在尝试为 Capistrano 3 编写一个任务,该任务涉及在当前版本的目录中执行“composer install”。它看起来像这样:

namespace :composer do
  desc 'Install dependencies with Composer'
  task :install do
    on roles(:web) do
      within release_path do
        execute "#fetch(:composer_command) install"
      end
    end
  end
end

composer_command 在暂存和生产文件中设置 - 在我的特定情况下为 php /home/user/composer.phar

由于某种原因,此命令实际上并未在当前发布目录中运行,而是在父目录中运行(包含当前、共享、发布等)

我对此进行了深入研究,发现当我运行一个单词命令时,例如:

within release_path do
    execute "pwd"
end

它工作得很好,并在当前发布目录中运行命令。 但是...当我运行带有空格的命令时,例如:

within release_path do
    execute "pwd && ls"
end

它在父目录中运行,而不是within 块设置的目录。

有人可以解释一下吗?谢谢!

【问题讨论】:

【参考方案1】:

闻起来像 Cap 3 的臭虫。

我建议只是从 shell 的角度保证你在你想去的地方:

execute "cd '#release_path'; #fetch(:composer_command) install"

【讨论】:

我提出了一个问题 - github.com/capistrano/capistrano/issues/719 原来这是 SSHKit 的一个约束。所以我会采用你的解决方案 - 旧的 capistrano 2 方式。 解释了in the docs。见this answer。【参考方案2】:

您可以保留within()with()default_env 等的所有细节,同时仍保持自然字符串语法:

within release_path do
  execute *%w[ pip install -r requirements.txt ]
end

【讨论】:

【参考方案3】:

几个提示:

1) Capistrano 将SSHKit 用于很多事情,其中​​包括命令执行。为了简化 Composer 的使用,您可以配置命令映射(deploy.rbproduction.rb 等),这里有 2 个示例:

SSHKit.config.command_map[:composer] = "#shared_path.join('composer.phar')"
SSHKit.config.command_map[:composer] = '/usr/bin/env composer.phar'

接下来你可以像这样执行它:

execute :composer, :install

2) 从安全角度来看,禁用 php 设置 allow_url_fopen 是明智之举,但不幸的是,Composer 需要启用它才能运行。您可以使用此技巧将其全局禁用:

SSHKit.config.command_map[:composer] = "/usr/bin/env php -d allow_url_fopen=On #shared_path.join('composer.phar')"

查看iniscan 了解有关 php 设置的更多安全建议。

3) Composer 有一个选项-d, --working-dir,您可以指向包含composer.json 文件的目录,以便从任何其他目录运行 Composer。这应该可以解决您的问题:

execute :composer, '-d', release_path, :install

4) 你可能想看看capistrano-composer 项目:)

【讨论】:

不知道这是否是由于 Capistrano 的更新,还是我的特定构建案例,但我需要做的是将您的第二个示例稍微修改为:我的 deploy.rb 中的 SSHKit.config.command_map[:composer] = "/[direct full path to]/composer.phar"。之后,在我的 .rake 文件中添加 `execute :composer, "install" 效果很好。【参考方案4】:

实际上,您对within 函数的使用几乎是正确的。您已将整个字符串作为命令提供给它,但文档指出这会导致不可靠的行为(我自己经历过)。

execute 的第一个参数是符号而不是字符串(包含空格):

within release_path do
    execute fetch(:composer_command).to_sym, "install"
    execute :pwd
    execute :ls
end

【讨论】:

【参考方案5】:

这里仅供参考,Capistrano Doc 解释了为什么within 不适用于带有空格的参数。我希望这会有所帮助。

【讨论】:

以上是关于Capistrano 3 在目录中执行的主要内容,如果未能解决你的问题,请参考以下文章

Capistrano 3 须藤任务

rails 布署

是否可以在 Capistrano 3 中转发 X11 窗口?

使用Capistrano 3部署git子模块

在 Capistrano 中部署 Git 子目录

如何在 Capistrano 中切换远程用户