Come distribuire su un singolo server specifico utilizzando Capistrano
-
07-07-2019 - |
Domanda
Ho un sistema in produzione che ha diversi server in diversi ruoli. Vorrei testare un nuovo server di app distribuendolo su quel server specifico, senza dover ridistribuire su tutti i server in produzione. C'è un modo per chiedere a Capistrano di distribuirlo su un server specifico? Idealmente, vorrei essere in grado di eseguire qualcosa del tipo
cap SERVER=app2.example.com ROLE=app production deploy
se volevo solo distribuire in app2.example.com.
Grazie!
[update] Ho provato la soluzione suggerita da wulong eseguendo:
cap HOSTS=app2.server.hostname ROLE=app qa deploy
ma sembra che capistrano stia cercando di eseguire attività per altri ruoli su quel server oltre alle attività dell'app. Forse devo aggiornare la mia versione di cap (sto eseguendo v2.2.0)?
Soluzione
Ho finito per pubblicare una domanda nell'elenco degli utenti di capistrano qui e ho ottenuto la seguente risposta da Jamis (modificato un po 'da me qui per chiarezza):
Prova la variabile di ambiente HOSTS:
cap HOSTS=app2.example.com production deploy
Tieni presente che facendo ciò tratterai app2 come in ogni ruolo, non solo in qualunque ruolo si verifichi.
Se quello che vuoi è fare una distribuzione regolare, ma agisci solo su app2 e solo quando app2 viene dichiarata nel file della ricetta, puoi utilizzare HOSTFILTER variabile invece:
cap HOSTFILTER=app2.example.com production deploy
[...]
Considera questo esempio concreto. Supponi il tuo lo script definisce tre server, A, B e C. E definisce un'attività, "pippo", che (per impostazione predefinita) vuole essere eseguito su A e B, ma non su C. In questo modo:
role :app, "A", "B"
role :web, "C"
task :foo, :roles => :app do
run "echo hello"
end
Ora, se si esegue cap foo
, verrà eseguito il comando echo su A e B.
Se si esegue cap HOSTS = C foo
, verrà eseguito il comando echo su C,
indipendentemente dal parametro: ruoli all'attività.
Se si esegue cap HOSTFILTER = C foo
, non verrà eseguito il comando echo su
tutto, perché l'intersezione di (A B) e (C) è un insieme vuoto. (Là
non ci sono host nella lista degli host di foo che corrispondono a C.)
Se si esegue cap HOSTFILTER = A foo
, eseguirà il comando echo solo su
A, perché (A B) intersecato con (A) è (A).
Infine, se si esegue cap HOSTFILTER = A, B, C foo
, verrà eseguito l'eco
comando su A e B (ma non C), perché (A B) si intersecano con (A B C)
è (A B).
Per riassumere: HOSTS sostituisce completamente la dichiarazione degli host o dei ruoli dell'attività e forza l'esecuzione di tutto contro l'host o gli host specificati. L'HOSTFILTER, d'altra parte, filtra semplicemente gli host esistenti rispetto all'elenco indicato, scegliendo solo quei server che sono già presenti l'elenco dei server delle attività.
Altri suggerimenti
Quanto segue dovrebbe funzionare immediatamente:
cap HOSTS=app2.example.com ROLE=app deploy
Se vuoi distribuire su > 1 server con lo stesso ruolo:
cap HOSTS=app2.example.com,app3.example.com,app4.example.com ROLE=app deploy
Ho un problema simile e ho provato quanto segue. Funziona:
cap production ROLES=web HOSTS=machine1 stats
Dovresti essere in grado di fare qualcosa del genere in deploy.rb:
task :production do
if ENV['SERVER'] && ENV['ROLE']
role ENV['ROLE'], ENV['SERVER']
else
# your full config
end
end
È inoltre possibile specificare il parametro host a livello di attività in questo modo:
task :ship_artifacts, :hosts => ENV['DEST_HOST'] do
end