60

我有一个生产系统,其中有多个服务器担任多个角色。我想通过部署到该特定服务器来测试新的应用服务器,而不必重新部署到生产中的每个服务器。有没有办法让 Capistrano 部署到特定的服务器?理想情况下,我希望能够运行类似的东西

cap SERVER=app2.example.com ROLE=app production deploy

如果我只想部署到 app2.example.com。

谢谢!

[更新]我通过执行尝试了wulong建议的解决方案:

cap HOSTS=app2.server.hostname ROLE=app qa deploy 

但 capistrano 似乎试图在该服务器上执行除应用程序任务之外的其他角色的任务。也许我需要更新我的 cap 版本(我正在运行 v2.2.0)?

4

5 回答 5

128

我最终在 capistrano 用户列表上发布了一个问题并得到了 Jamis 的以下回复(为清楚起见,我在此处进行了一些编辑):


尝试 HOSTS 环境变量:

cap HOSTS=app2.example.com production deploy

请注意,这样做会将 app2 视为处于每个角色中,而不仅仅是恰好在其中声明的任何角色中。

如果您想要进行常规部署,但仅对 app2 执行操作,并且仅当 app2 在配方文件中声明时,您可以改用 HOSTFILTER 变量:

cap HOSTFILTER=app2.example.com production deploy 

[...]

考虑这个具体的例子。假设您的脚本定义了三个服务器 A、B 和 C。它定义了一个任务“foo”,它(默认情况下)希望在 A 和 B 上运行,而不是在 C 上运行。像这样:

role :app, "A", "B"
role :web, "C"

task :foo, :roles => :app do
  run "echo hello"
end

现在,如果你这样做cap foo,它将在 A 和 B 上运行 echo 命令。

如果这样做cap HOSTS=C foo,它将在 C 上运行 echo 命令,而不管任务的 :roles 参数如何。

如果你这样做cap HOSTFILTER=C foo,它根本不会运行 echo 命令,因为 (AB) 和 (C) 的交集是一个空集。(foo 的主机列表中没有与 C 匹配的主机。)

如果这样做cap HOSTFILTER=A foo,它将仅在 A 上运行 echo 命令,因为与 (A) 相交的 (AB) 是 (A)。

最后,如果你这样做cap HOSTFILTER=A,B,C foo,它将在 A 和 B(但不是 C)上运行 echo 命令,因为 (AB) 与 (ABC) 相交是 (AB)。

总结一下:HOSTS 完全覆盖任务的主机或角色声明,并强制所有内容针对指定的主机运行。另一方面,HOSTFILTER 只是根据给定列表过滤现有主机,只选择那些已经在任务服务器列表中的服务器。

于 2009-01-22T19:59:02.817 回答
3

以下应该是开箱即用的:

cap HOSTS=app2.example.com ROLE=app deploy

如果要部署到具有相同角色的 >1 台服务器:

cap HOSTS=app2.example.com,app3.example.com,app4.example.com ROLE=app deploy
于 2009-01-11T00:49:46.633 回答
2

我有类似的问题并尝试了以下方法。有用:

cap production ROLES=web HOSTS=machine1 stats
于 2011-01-24T02:00:02.043 回答
1

您应该可以在 deploy.rb 中执行以下操作:

task :production do
  if ENV['SERVER'] && ENV['ROLE']
    role ENV['ROLE'], ENV['SERVER']
  else
    # your full config
  end
end
于 2009-01-10T02:27:34.877 回答
0

您还可以通过这种方式指定任务级主机参数:

task :ship_artifacts, :hosts => ENV['DEST_HOST']  do

end 
于 2015-03-11T07:53:37.883 回答