Cómo implementar en un único servidor específico utilizando Capistrano
-
07-07-2019 - |
Pregunta
Tengo un sistema en producción que tiene varios servidores en varios roles. Me gustaría probar un nuevo servidor de aplicaciones mediante la implementación en ese servidor específico, sin tener que volver a implementar en cada servidor en producción. ¿Hay alguna manera de pedirle a Capistrano que se implemente en un servidor específico? Idealmente, me gustaría poder ejecutar algo como
cap SERVER=app2.example.com ROLE=app production deploy
si solo quisiera implementarlo en app2.example.com.
¡Gracias!
[actualización] Probé la solución sugerida por wulong ejecutando:
cap HOSTS=app2.server.hostname ROLE=app qa deploy
pero capistrano parecía estar tratando de ejecutar tareas para otros roles en ese servidor además de las tareas de la aplicación. ¿Quizás necesito actualizar mi versión de cap (estoy ejecutando v2.2.0)?
Solución
Terminé publicando una pregunta en la lista de usuarios de capistrano aquí , y obtuve la siguiente respuesta de Jamis (editado un poco por mí para mayor claridad):
Pruebe la variable de entorno HOSTS:
cap HOSTS=app2.example.com production deploy
Tenga en cuenta que al hacer esto, se tratará a app2 como un rol en cada rol, no solo cualquiera de los roles en los que se declare.
Si lo que quiere es hacer una implementación regular, pero solo actuar en la aplicación2, y solo cuando se declara app2 en su archivo de recetas, puede usar el HOSTFILTER variable en su lugar:
cap HOSTFILTER=app2.example.com production deploy
[...]
Considere este ejemplo concreto. Supongamos que tu El script define tres servidores, A, B y C. Y define una tarea, "foo", que (por defecto) quiere ejecutarse en A y B, pero no en C. De esta manera:
role :app, "A", "B"
role :web, "C"
task :foo, :roles => :app do
run "echo hello"
end
Ahora, si haces cap foo
, ejecutará el comando echo en A y B.
Si haces cap HOSTS = C foo
, ejecutará el comando echo en C,
independientemente del parámetro: roles para la tarea.
Si haces cap HOSTFILTER = C foo
, no ejecutará el comando echo en
todo, porque la intersección de (A B) y (C) es un conjunto vacío. (Ahí
no hay hosts en la lista de hosts de foo que coincidan con C.)
Si haces cap HOSTFILTER = A foo
, ejecutará el comando echo solo
A, porque (A B) intersectado con (A) es (A).
Por último, si haces cap HOSTFILTER = A, B, C foo
, se ejecutará el eco
comando en A y B (pero no en C), porque (A B) se cruzó con (A B C)
es (A B).
Para resumir: HOSTS anula completamente la declaración de hosts o roles de la tarea, y obliga a todo a ejecutarse contra los hosts especificados. El HOSTFILTER, por otro lado, simplemente filtra los hosts existentes. contra la lista dada, eligiendo solo aquellos servidores que ya están en la lista de servidores de tareas.
Otros consejos
Lo siguiente debería funcionar fuera de la caja:
cap HOSTS=app2.example.com ROLE=app deploy
Si desea implementar en > 1 servidor con la misma función:
cap HOSTS=app2.example.com,app3.example.com,app4.example.com ROLE=app deploy
Tengo un problema similar y probé lo siguiente. Funciona:
cap production ROLES=web HOSTS=machine1 stats
Debería poder hacer algo como esto en deploy.rb:
task :production do
if ENV['SERVER'] && ENV['ROLE']
role ENV['ROLE'], ENV['SERVER']
else
# your full config
end
end
También puede especificar el parámetro hosts de nivel de tarea de esta manera:
task :ship_artifacts, :hosts => ENV['DEST_HOST'] do
end