如何使用Capistrano将代码部署到单个特定的服务器

61

我正在生产环境使用一个系统,它有几个服务器扮演不同的角色。我想测试一个新的应用服务器,只需要将其部署到特定的服务器上,而无需重新部署到生产环境中的每个服务器。是否有一种方法可以要求Capistrano部署到特定的服务器?理想情况下,我希望能够运行类似以下命令:

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

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

谢谢!

[更新] 我尝试了wulong提出的解决方案,执行如下:

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

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

5个回答

130

我最终在capistrano用户列表这里发布了一个问题,并从Jamis那里得到以下回复(为了清晰起见,这里稍作编辑):


尝试使用HOSTS环境变量:

cap HOSTS=app2.example.com production deploy
请注意,这样做将把app2视为每个角色而不仅仅是其声明的任何角色。
如果您想进行常规部署,但仅在处理recipe文件中声明的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命令, 因为(A B)和(C)的交集是一个空集。(foo的主机列表中没有与C匹配的主机。)

如果您执行cap HOSTFILTER=A foo,它将仅在A上运行echo命令, 因为(A B)与(A)的交集为(A)。

最后,如果您执行cap HOSTFILTER=A,B,C foo,它将在A和B(但不是C)上运行echo命令, 因为(A B)与(A B C)的交集为(A B)。

总之:

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


1
看起来这个在 Capistrano 3.4 上已经不再起作用了。 - collimarco
在 Capistrano 3 中,你将使用 HOSTS 环境变量来代替 Capistrano 2 中的 HOSTFILTER。http://capistranorb.com/documentation/advanced-features/host-filtering/ - codener

3
以下内容应该可以直接使用:
cap HOSTS=app2.example.com ROLE=app deploy

如果您想在多台服务器上部署相同的角色:
cap HOSTS=app2.example.com,app3.example.com,app4.example.com ROLE=app deploy

1
我尝试了第一种情况(部署到单个应用服务器),执行以下命令: cap HOSTS=app2.server.hostname ROLE=app qa deploy 但是,Capistrano 似乎还在尝试执行该服务器上其他角色的任务,除了 app 任务。也许我需要更新我的 Cap 版本(我正在运行 2.2.0)。 - Pete Hodgson
HOSTFILTER是答案,但这不是你想要的。 - Henley

2

我有类似的问题,尝试了以下方法。它有效:

cap production ROLES=web HOSTS=machine1 stats

1

你应该能够在 deploy.rb 中做类似这样的事情:

task :production do
  if ENV['SERVER'] && ENV['ROLE']
    role ENV['ROLE'], ENV['SERVER']
  else
    # your full config
  end
end

0

您也可以通过以下方式指定任务级别的主机参数:

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

end 

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接