Capistrano 3在目录中执行

Rah*_*har 30 ruby capistrano ruby-on-rails composer-php capistrano3

我正在尝试为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
Run Code Online (Sandbox Code Playgroud)

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

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

我深入研究了这一点,发现当我运行单个单词命令时,如:

within release_path do
    execute "pwd"
end
Run Code Online (Sandbox Code Playgroud)

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

within release_path do
    execute "pwd && ls"
end
Run Code Online (Sandbox Code Playgroud)

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

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

小智 31

闻起来像Cap 3的bug.

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

execute "cd '#{release_path}'; #{fetch(:composer_command)} install"
Run Code Online (Sandbox Code Playgroud)

  • 这不是一个错误.这是SSHKit的工作方式.看到其他答案. (4认同)
  • 我提出了一个问题 - https://github.com/capistrano/capistrano/issues/719原来这是SSHKit的约束.所以我会选择你的解决方案 - 旧的capistrano 2方式,就像它一样. (3认同)

bri*_*ker 9

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

within release_path do
  execute *%w[ pip install -r requirements.txt ]
end
Run Code Online (Sandbox Code Playgroud)


Jas*_*wer 7

一些提示:

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'
Run Code Online (Sandbox Code Playgroud)

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

execute :composer, :install
Run Code Online (Sandbox Code Playgroud)

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')}"
Run Code Online (Sandbox Code Playgroud)

查看iniscan以获取有关php设置的更多安全建议.

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

execute :composer, '-d', release_path, :install
Run Code Online (Sandbox Code Playgroud)

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


Jel*_*Cat 5

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

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

within release_path do
    execute fetch(:composer_command).to_sym, "install"
    execute :pwd
    execute :ls
end
Run Code Online (Sandbox Code Playgroud)