2016-07-19 27 views
1

Ich habe meine Rails (4.2) App läuft durch Passenger (5.0.28) + Apache (2.4.7) auf einem Ubuntu (14.02) -System, Ruby (2.3.0) verwaltet mit rbenv. Ich stelle mit Capistrano (3.4.0) bereit.Zugriff auf Umgebungsvariablen während der Bereitstellung von Capistrano?

Alle meine Umgebungsvariablen sind in einem sehr einfachen profile.d Skript festgelegt.

#!/bin/sh 
export VAR1=VAL1 
export VAR2=VAL2 

Dies funktioniert wie ein Charme. Meine App ENV hat alle richtigen Variablen, Secrets.yml ist richtig ausgefüllt ... alles funktioniert, außer für die Bereitstellung mit Capistrano über ssh.

In meinem deploy.rb Ich habe folgendes, dass ich denke, ist relavant:

set :ssh_options, { 
forward_agent: true, 
paranoid: true, 
keys: "~/.ssh/id_rsa.pub" 
} 

Capistrano docs unglaublich begrenzt und ssh \ server sein Config nicht meine Stärke kann ich nicht, warum meine ENV Variablen scheinen, um herauszufinden werden von Capistrano nicht gesehen. Wenn ich während des Bereitstellungsablaufs puts ENV.inspect ausführen, erhalte ich Dinge wie "TERM_PROGRAM"=>"Apple_Terminal" und meine lokalen Computerbenutzerinformationen und was nicht. Warum verwendet Capistrano nicht die Remote-Umgebung? Wie kann ich meine Konfiguration entweder serverseitig oder in meinem Bereitstellungsskript ändern, um dies zu beheben?

Danke für die Hilfe.

Antwort

3

Zuerst denke ich, dass eine Klarstellung der Terminologie und Capistrano's Ausführungsmodell benötigt wird.

Capistrano ist ein Programm, das auf Ihrem lokalen Computer ausgeführt wird. So sieht ENV in Capistrano Ihre lokale Umgebung, nicht die des Servers. Es gibt keine Möglichkeit für Capistrano, die entfernte ENV mit einfachem Ruby-Code zu "sehen", weil der Ruby-Code, der Capistrano bildet, dort nicht ausgeführt wird.

Was Capistrano tut tun wird SSH verwenden, um Befehle an den Server zu senden, dort ausgeführt werden. Befehle wie mkdir, bundle install und so weiter.

Um dies dargestellt ist, eine Capistrano Aufgabe der Bereitstellung Fluss hinzufügen, das dies tut:

task :puts_remote_env do 
    on roles(:all) do 
    remote_env = capture("env") 
    puts remote_env 
    end 
end 

Dies wird den env Befehl auf dem Remote-Server, erfassen das Ergebnis, und drucken Sie es zu Ihrer Konsole laufen.

Ich hoffe, dies macht es klarer, wie Capistrano funktioniert.


So, wie Sie von der puts_remote_env Ausgabe sehen können, die in Ihrem profile.d Skript definierten Variablen gibt es nicht. Warum?

Es ist, weil Capistrano eine non-login, nicht interaktive SSH Sitzung verwendet. In dieser SSH-Sitzung wird Ihr Skript profile.d nicht ausgewertet. Dies wird detailliert in den FAQ zu Capistrano erklärt: http://capistranorb.com/documentation/faq/why-does-something-work-in-my-ssh-session-but-not-in-capistrano/

Sie müssen einen anderen Weg finden, um diese Variablen außer profile.d Skript zu setzen.

Sie können sie in Ihrer Capistrano-Konfiguration selbst angeben (z.production.rb) wie folgt aus:

set :default_env, { var1: "val1", var2: "val2" } 

Capistrano wird dann diese Umgebung explizit festgelegt, wenn es SSH-Befehle ausführt.

Oder Sie könnten ein Tool wie dotenv verwenden, das es Rails ermöglicht, Variablenvariablen aus einer speziellen Datei zu lesen, anstatt sich auf die Ausführungsumgebung zu verlassen.

Oder Sie könnten mit verschiedenen Speicherorten von Punktdateien experimentieren, um zu sehen, ob es noch welche gibt, die auch in einer Sitzung ohne Login und ohne Interaktion ausgewertet werden. Auf Ubuntu hatte ich Erfolg beim Exportieren von Variablen an der Spitze von ~/.bashrc.

+1

Ausgezeichnete Antwort. –

+0

Vielen Dank, dass Sie sich die Zeit genommen haben, das zu schreiben. Diese Tabelle am Ende des Links ist fantastisch. –