如何使用Capistrano部署到单个特定服务器

时间:2021-04-19 01:24:13

I have a system in production that has several servers in several roles. I would like to test a new app server by deploying to that specific server, without having to redeploy to every server in production. Is there a way to ask Capistrano to deploy to a specific server? Ideally I'd like to be able to run something like

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

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

if I just wanted to deploy to app2.example.com.

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

Thanks!

[update] I tried the solution suggested by wulong by executing:

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

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

but capistrano seemed be trying to execute tasks for other roles on that server in addition to app tasks. Maybe I need to update my version of cap (I'm running v2.2.0)?

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

5 个解决方案

#1


I ended up posting a question on the capistrano users list here, and got the following response from Jamis (edited a bit by me here for clarity):

我最后在capistrano用户列表上发布了一个问题,得到了Jamis的以下回复(为了清楚起见,我在这里编辑了一下):


Try the HOSTS environment variable:

尝试HOSTS环境变量:

cap HOSTS=app2.example.com production deploy

Note that doing this will treat app2 as being in every role, not just whichever role(s) it happens to be declared in.

请注意,执行此操作会将app2视为处于每个角色中,而不仅仅是将其声明为哪个角色。

If what you want is to do a regular deploy, but only act on app2, and only as app2 is declared in your recipe file, you can use the HOSTFILTER variable instead:

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

cap HOSTFILTER=app2.example.com production deploy 

[...]

Consider this concrete example. Suppose your script defines three servers, A, B, and C. And it defines a task, "foo", that (by default) wants to run on A and B, but not C. Like this:

考虑这个具体的例子。假设你的脚本定义了三个服务器,A,B和C.它定义了一个任务,“foo”,(默认情况下)想要在A和B上运行,但不能在C上运行。像这样:

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

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

Now, if you do cap foo, it will run the echo command on both A and B.

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

If you do cap HOSTS=C foo, it will run the echo command on C, regardless of the :roles parameter to the task.

如果确实限制了HOSTS = C foo,它将在C上运行echo命令,而不管任务的:roles参数如何。

If you do cap HOSTFILTER=C foo, it will not run the echo command at all, because the intersection of (A B) and (C) is an empty set. (There are no hosts in foo's host list that match C.)

如果确实限制了HOSTFILTER = C foo,它根本不会运行echo命令,因为(A B)和(C)的交集是空集。 (foo的主机列表中没有与C匹配的主机。)

If you do cap HOSTFILTER=A foo, it will run the echo command on only A, because (A B) intersected with (A) is (A).

如果确实限制了HOSTFILTER = A foo,它将仅在A上运行echo命令,因为(A B)与(A)相交的是(A)。

Lastly, if you do cap HOSTFILTER=A,B,C foo, it will run the echo command on A and B (but not C), because (A B) intersected with (A B C) is (A B).

最后,如果你确实限制HOSTFILTER = A,B,C foo,它将在A和B(但不是C)上运行echo命令,因为(A B)与(A B C)相交的是(A B)。

To summarize: HOSTS completely overrides the hosts or roles declaration of the task, and forces everything to run against the specified host(s). The HOSTFILTER, on the other hand, simply filters the existing hosts against the given list, choosing only those servers that are already in the tasks server list.

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

#2


The following should work out of the box:

以下应该开箱即用:

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

If you want to deploy to >1 server with the same role:

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

cap HOSTS=app2.example.com,app3.example.com,app4.example.com ROLE=app deploy

#3


I have similar problem and tried the following. It works:

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

cap production ROLES=web HOSTS=machine1 stats

#4


You should be able to do something like this in deploy.rb:

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

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

#5


You can also specifiy task-level hosts parameter this way:

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

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

end 

#1


I ended up posting a question on the capistrano users list here, and got the following response from Jamis (edited a bit by me here for clarity):

我最后在capistrano用户列表上发布了一个问题,得到了Jamis的以下回复(为了清楚起见,我在这里编辑了一下):


Try the HOSTS environment variable:

尝试HOSTS环境变量:

cap HOSTS=app2.example.com production deploy

Note that doing this will treat app2 as being in every role, not just whichever role(s) it happens to be declared in.

请注意,执行此操作会将app2视为处于每个角色中,而不仅仅是将其声明为哪个角色。

If what you want is to do a regular deploy, but only act on app2, and only as app2 is declared in your recipe file, you can use the HOSTFILTER variable instead:

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

cap HOSTFILTER=app2.example.com production deploy 

[...]

Consider this concrete example. Suppose your script defines three servers, A, B, and C. And it defines a task, "foo", that (by default) wants to run on A and B, but not C. Like this:

考虑这个具体的例子。假设你的脚本定义了三个服务器,A,B和C.它定义了一个任务,“foo”,(默认情况下)想要在A和B上运行,但不能在C上运行。像这样:

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

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

Now, if you do cap foo, it will run the echo command on both A and B.

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

If you do cap HOSTS=C foo, it will run the echo command on C, regardless of the :roles parameter to the task.

如果确实限制了HOSTS = C foo,它将在C上运行echo命令,而不管任务的:roles参数如何。

If you do cap HOSTFILTER=C foo, it will not run the echo command at all, because the intersection of (A B) and (C) is an empty set. (There are no hosts in foo's host list that match C.)

如果确实限制了HOSTFILTER = C foo,它根本不会运行echo命令,因为(A B)和(C)的交集是空集。 (foo的主机列表中没有与C匹配的主机。)

If you do cap HOSTFILTER=A foo, it will run the echo command on only A, because (A B) intersected with (A) is (A).

如果确实限制了HOSTFILTER = A foo,它将仅在A上运行echo命令,因为(A B)与(A)相交的是(A)。

Lastly, if you do cap HOSTFILTER=A,B,C foo, it will run the echo command on A and B (but not C), because (A B) intersected with (A B C) is (A B).

最后,如果你确实限制HOSTFILTER = A,B,C foo,它将在A和B(但不是C)上运行echo命令,因为(A B)与(A B C)相交的是(A B)。

To summarize: HOSTS completely overrides the hosts or roles declaration of the task, and forces everything to run against the specified host(s). The HOSTFILTER, on the other hand, simply filters the existing hosts against the given list, choosing only those servers that are already in the tasks server list.

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

#2


The following should work out of the box:

以下应该开箱即用:

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

If you want to deploy to >1 server with the same role:

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

cap HOSTS=app2.example.com,app3.example.com,app4.example.com ROLE=app deploy

#3


I have similar problem and tried the following. It works:

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

cap production ROLES=web HOSTS=machine1 stats

#4


You should be able to do something like this in deploy.rb:

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

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

#5


You can also specifiy task-level hosts parameter this way:

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

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

end