Capistrano 3在目录中执行

我正在尝试为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块设置的目录。

有人可以对此有所了解吗? 谢谢!

闻起来像Cap 3 bug。

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

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

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

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

一些提示:

1)Capistrano使用SSHKit进行很多操作,其中包括命令执行。 为了简化使用Composer,您可以配置命令映射(在deploy.rbproduction.rb等中),这里有两个示例:

 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项目:)

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

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

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

这里仅供参考,是Capistrano Doc解释为什么within {}不能与空格的参数一起使用。 我希望这有帮助。