So beheben Sie den Fehler "Fehlende" secret_key_base "für" Produktionsumgebung "" (Rails 4.1)


169

Ich habe mit Rails 4.1 eine Rails-Anwendung von Grund auf neu erstellt und stehe vor einem seltsamen Problem, das ich nicht lösen kann.

Jedes Mal, wenn ich versuche, meine Anwendung auf Heroku bereitzustellen, wird die Fehlermeldung 500 angezeigt:

Missing `secret_key_base` for 'production' environment, set this value in `config/secrets.yml`

Die secret.ymlDatei enthält die folgende Konfiguration:

secret_key_base: <%= ENV["SECRET_KEY_BASE"] %>

Auf Heroku habe ich die SECRET_KEY_BASEUmgebungsvariable " " mit dem Ergebnis des rake secretBefehls konfiguriert . Wenn ich starte heroku config, kann ich die Variable mit dem richtigen Namen und Wert sehen.

Warum erhalte ich diesen Fehler immer noch?


1
Ich habe genau das gleiche Problem und würde gerne wissen, warum dies auch passiert. Wenn ich herausfinde warum, werde ich meine Lösung zurückschicken.
Danielricecodes

Wird Ihre Konfigurationsdatei aufgerufen secret.ymloder secrets.yml?
James

2
Ich habe die .gitignore-Datei erneut mit der von Rails generierten konfiguriert und jetzt funktioniert alles einwandfrei
Paolo Laurenti

Dieses Problem trat auch beim Upgrade auf Rails 4 auf. In unserem Fall lag dies daran, dass wir einen benutzerdefinierten Umgebungsnamen hatten, der sich nicht in secret.yml widerspiegelte. Ich musste der Datei nur eine Zeile mit dem nicht standardmäßigen Namen hinzufügen, festschreiben und erneut bereitstellen.
Whognu

Für zukünftige Leser: Diese Antwort ist wahrscheinlich die einfachste und genaueste: stackoverflow.com/a/26541742/4880924
BKSpurgeon

Antworten:


208

Ich hatte das gleiche Problem und löste es, indem ich eine Umgebungsvariable erstellte, die jedes Mal geladen werden sollte, wenn ich mich beim Produktionsserver anmeldete, und eine Kurzanleitung der Schritte zum Konfigurieren erstellte:

Ich habe Rails 4.1 mit Unicorn v4.8.2 verwendet und als ich versuchte, meine Anwendung bereitzustellen, wurde sie nicht richtig gestartet und in der unicorn.logDatei fand ich folgende Fehlermeldung:

app error: Missing `secret_key_base` for 'production' environment, set this value in `config/secrets.yml` (RuntimeError)

Nach einigen Recherchen habe ich herausgefunden, dass Rails 4.1 die Art und Weise der Verwaltung geändert hat. secret_keyWenn Sie also die secrets.ymlDatei unter lesen, exampleRailsProject/config/secrets.ymlfinden Sie Folgendes:

# Do not keep production secrets in the repository,
# instead read values from the environment.
production:
  secret_key_base: <%= ENV["SECRET_KEY_BASE"] %>

Dies bedeutet, dass Rails Ihnen empfiehlt, eine Umgebungsvariable für die secret_key_basein Ihrem Produktionsserver zu verwenden. Um diesen Fehler zu beheben, sollten Sie die folgenden Schritte ausführen, um eine Umgebungsvariable für Linux (in meinem Fall Ubuntu) auf Ihrem Produktionsserver zu erstellen:

  1. Führen Sie im Terminal Ihres Produktionsservers Folgendes aus:

    $ RAILS_ENV=production rake secret

    Dies gibt eine große Zeichenfolge mit Buchstaben und Zahlen zurück. Kopieren Sie das, als das wir diesen Code bezeichnen werden GENERATED_CODE.

  2. Melden Sie sich bei Ihrem Server an

    • Wenn Sie sich als Root anmelden, suchen Sie diese Datei und bearbeiten Sie sie:

      $ vi /etc/profile

      Gehen Sie mit Shift+ G(Großbuchstabe "G") in vi zum Ende der Datei .

      Schreiben Sie Ihre Umgebungsvariable mit GENERATED_CODEund drücken Sie i, um in vi einzufügen. Stellen Sie sicher, dass Sie am Ende der Datei in einer neuen Zeile stehen:

      $ export SECRET_KEY_BASE=GENERATED_CODE

      Speichern Sie die Änderungen und schließen Sie die Datei mit Escund dann " :x" und Enterzum Speichern und Beenden in vi.

    • Wenn Sie sich jedoch als normaler Benutzer anmelden, nennen wir es " example_user" für diesen Kern. Sie müssen eine dieser anderen Dateien finden:

      $ vi ~/.bash_profile
      $ vi ~/.bash_login
      $ vi ~/.profile
      

      Diese Dateien sind in der Reihenfolge ihrer Wichtigkeit angeordnet. Wenn Sie also die erste Datei haben, müssen Sie die anderen nicht bearbeiten. Wenn Sie diese beiden Dateien in Ihrem Verzeichnis gefunden haben ~/.bash_profileund ~/.profilenur die erste schreiben müssen, ~/.bash_profileliest Linux nur diese und die andere wird ignoriert.

      Dann gehen wir erneut mit Shift+ zum Ende der Datei Gund schreiben die Umgebungsvariable mit unserer erneuten GENERATED_CODEVerwendung ierneut. Fügen Sie am Ende der Datei eine neue Zeile hinzu:

      $ export SECRET_KEY_BASE=GENERATED_CODE

      Nachdem Sie den Code geschrieben haben, speichern Sie die Änderungen und schließen Sie die Datei mit Escerneut und " :x" und Enterzum Speichern und Beenden.

  3. Mit diesem Befehl können Sie überprüfen, ob unsere Umgebungsvariable unter Linux richtig eingestellt ist:

    $ printenv | grep SECRET_KEY_BASE

    oder mit:

    $ echo $SECRET_KEY_BASE

    Wenn Sie diesen Befehl ausführen und alles in Ordnung ist, wird Ihnen das GENERATED_CODEvon zuvor angezeigt. Nach Abschluss der Konfiguration sollten Sie in der Lage sein, Ihre Rails-Anwendung problemlos mit Unicorn oder einem anderen Tool bereitzustellen.

Wenn Sie Ihre Shell schließen und sich erneut beim Produktionsserver anmelden, ist diese Umgebungsvariable festgelegt und kann verwendet werden.

Und das ist es! Ich hoffe, dieser Mini-Guide hilft Ihnen, diesen Fehler zu beheben.

Haftungsausschluss: Ich bin kein Linux- oder Rails-Guru. Wenn Sie also etwas falsch finden oder einen Fehler finden, kann ich ihn gerne beheben.


11
Es scheint, dass Rails die Umgebungsvariable SECRET_KEY_BASE nicht sieht. printenv zeigt es, Schienen c Produktion zeigt es auch, wenn ich ENV inspiziere. Aber ich habe keine Auswirkung, wenn ich Unicorn neu starte. Der einzige Weg, der jetzt funktioniert, ist das direkte Einfügen in Secrets.yml
AntonAL

1
Das hat bei mir funktioniert. Vielen Dank für Ihre vollständige Erklärung. Ich habe gerade erfahren, dass es Juwelen für die Verwaltung der Umgebungsvariablen einer App gibt. 'Dotenv' ist einer und 'Vorarbeiter' für Heroku. Während es eine Ausbildung war, den Fehler manuell auf diese Weise zu beheben, kann die Verwendung eines dieser Edelsteine ​​den Prozess rationalisieren?
Nick Res

Ich bin froh, dass meine Antwort hilfreich war, danke für die Edelsteinoptionen @ ninja08, die den Prozess definitiv vereinfachen, hauptsächlich für diejenigen, die Capistrano oder ein anderes inkrementelles Tool zur Verwaltung des Servers verwenden :)
Demi Magus

Nach den hervorragenden Anweisungen von Demi Magus habe ich Folgendes gemacht: cd / var / www / Rails; rvm benutze ext-rbx-2.5.2@rails; SKB_FILE = / var / www / .secret_key_base; echo "export SECRET_KEY_BASE = $ (RAILS_ENV = Produktionsrechengeheimnis)"> $ SKB_FILE; . $ SKB_FILE; echo ". $ SKB_FILE" | tee -a ~ / .bashrc ~ / .bash_profile; chmod o-rwx $ SKB_FILE;
David Winiecki

Gute Antwort!! Ich weiß nicht, warum dies nicht für mich gelöst ist, ich erstelle eine Frage stackoverflow.com/questions/33117318/…
Adriano Resende

84

Ich gehe davon aus, dass Sie Ihre secrets.ymlQuellcodeverwaltung nicht eingecheckt haben (dh sie befindet sich in der .gitignoreDatei). Auch wenn dies nicht Ihre Situation ist, haben es viele andere Personen getan, die diese Frage sehen, weil sie ihren Code auf Github verfügbar gemacht haben und nicht möchten, dass ihr geheimer Schlüssel herumschwebt.

Wenn es nicht in der Quellcodeverwaltung ist, weiß Heroku nichts davon. Rails sucht also Rails.application.secrets.secret_key_baseund es wurde nicht festgelegt, da Rails es durch Überprüfen der secrets.ymlDatei festlegt, die nicht vorhanden ist. Die einfache Problemumgehung besteht darin, in Ihre config/environments/production.rbDatei zu gehen und die folgende Zeile hinzuzufügen:

Rails.application.configure do
    ...
    config.secret_key_base = ENV["SECRET_KEY_BASE"]
    ...
end

Dadurch wird Ihre Anwendung angewiesen, den geheimen Schlüssel mithilfe der Umgebungsvariablen festzulegen, anstatt ihn zu suchen secrets.yml. Es hätte mir viel Zeit gespart, dies von vornherein zu wissen.


15
Dies ist die beste Antwort. Figaround heroku_secretstu nichts, es sei denn, Rails weiß, dass das SECRET_KEY_BASElebt ENV. Ich hatte mit diesem Gedanken zu kämpfen, dass Rails, wenn die Konfigurationsvariable auf Heroku existieren würde, sie nur aufgrund ihrer Existenz aufgreifen würde, aber jetzt scheint es offensichtlich, dass Rails wissen müsste, wo sie suchen müssen. Ich habe mich gefragt, wie ich Code auf Github haben kann, ohne mir Gedanken über die geheime Schlüsselbasis machen zu müssen. jetzt weiß ich.
Flanger001

1
Einverstanden, ich denke, die Geheimnisse.yml ist überflüssig mit großen Edelsteinen wie Figaro.
Joe

2
Scheint die beste Option zu sein, wenn Sie Github und Heroku für Ihr Projekt verwenden.
Flexus

1
Was ist los mit mit Ihrem secrets.yml begehen production: secret_key_base: <%= ENV["SECRET_KEY_BASE"] %>. Bedeutet das nicht auch, dass der eigentliche geheime Schlüssel nicht offengelegt wird? Besteht das Risiko, Entwickler- und Testschlüssel in festgeschriebenen Secrets.yml offenzulegen, wenn es sich nur um Seed- und Testdaten handelt?
Jay Killeen

Dies funktioniert auch in Rails 6.0.2, wenn keine Secrets.yml mehr vorhanden ist.
Ken Tsoi

54

In config/secrets.ymlder Versionskontrolle und bereitstellen wieder. Möglicherweise müssen Sie eine Zeile aus entfernen, .gitignoredamit Sie die Datei festschreiben können.

Ich hatte genau das gleiche Problem und es stellte sich heraus, dass das .gitignorefür meine Rails-Anwendung erstellte Boilerplate Github enthalten war config/secrets.yml.


140
config / secrets.yml sollte nie in den Repo sein Sie es in mit gefälschten Daten do.yml.sample und füllen kann , aber für die Sicherheit, tun nie in repos .yml
user3379926

9
@ user3379926 Im Kontext einer Rails-App auf Heroku können Sie nicht auswählen, welche Dateien in der Versionskontrolle enthalten sind und welche nicht. Rails 4.1 erwartet, dass die geheime Konfiguration vorhanden ist, andernfalls wird die Anwendung nicht ausgeführt. Wenn Sie eine Möglichkeit haben, das in der obigen Frage aufgeworfene Problem zu beheben, ohne die Datei secret.yml in Git festzuschreiben, helfen Sie bitte, diesen Thread zu verbessern, indem Sie diesen Rat geben.
Danielricecodes

9
@danielricecodes Sie können den Wert in einem Initialisierer manuell festlegen. So etwas Rails.application.config.secret_key_base = ENV["SECRET_KEY_BASE"]würde funktionieren und den Fehler entfernen, ohne secrets.ymlzur Quelle hinzuzufügen .
Joshhepworth

11
@ user3379926: Wenn ich eine neue Rails-Anwendung mit generiere rails new(in diesem Fall eine Gem-Datei, deren Gem railsdie Version hat 4.2.4), wird die Datei config/secrets.ymlgeneriert. Es enthält vorgenerierte geheime Schlüssel für die Entwicklungs- und Testumgebung und liest den geheimen Schlüssel für die Produktionsumgebung aus einer Umgebungsvariablen : secret_key_base: <%= ENV["SECRET_KEY_BASE"] %>. Mir scheint, dass es absolut sicher und in der Tat nützlich ist, diese secrets.ymlDatei in der Versionskontrolle zu halten , vorausgesetzt, man definiert dort nie den geheimen Schlüssel.
Teemu Leisti

2
@ Jasonleonhard warum? Wenn Sie den geheimen Schlüssel von env vars trotzdem lesen, was ist die große Sache? Es werden keine Geheimnisse preisgegeben.
Horseyguy

13

Das hat bei mir funktioniert.

cdFühren Sie SSH in Ihren Produktionsserver und in Ihr aktuelles Verzeichnis aus, führen Sie es aus bundle exec rake secretoder rake secretkopieren Sie diese Zeichenfolge, wenn Sie eine lange Zeichenfolge als Ausgabe erhalten.

Jetzt renn sudo nano /etc/environment.

Fügen Sie am Ende der Datei ein

export SECRET_KEY_BASE=rake secret
ruby -e 'p ENV["SECRET_KEY_BASE"]'

Wo rake secretsich die gerade kopierte Zeichenfolge befindet, fügen Sie diese kopierte Zeichenfolge anstelle von ein rake secret.

Starten Sie den Server neu und testen Sie ihn durch Ausführen echo $SECRET_KEY_BASE.


3

Während Sie Initialisierer wie die anderen Antworten verwenden können, besteht die herkömmliche Methode von Rails 4.1+ darin, die zu verwenden config/secrets.yml. Der Grund für das Rails-Team, dies einzuführen, liegt außerhalb des Rahmens dieser Antwort, aber der TL; DR besteht darin, dass secret_token.rbKonfiguration und Code zusammengeführt werden und ein Sicherheitsrisiko darstellt, da das Token in den Versionsverwaltungsverlauf eingecheckt wird und das einzige System ist, das dies benötigt Ich weiß, dass das Produktionsgeheimnis die Produktionsinfrastruktur ist.

Sie sollten diese Datei .gitignoreso hinzufügen config/database.yml, als würden Sie sie auch nicht zur Quellcodeverwaltung hinzufügen .

Referenzierung Heroku eigenen Code für die Einrichtung config/database.ymlvon DATABASE_URLihrer Buildpack für Ruby , landete ich ihre Repo - gabeln und modifiziert es schaffen config/secrets.ymlvon SECRETS_KEY_BASEUmgebungsvariablen.

Da diese Funktion in Rails 4.1 eingeführt wurde, hielt ich es für angemessen, ./lib/language_pack/rails41.rbdiese Funktionalität zu bearbeiten und hinzuzufügen.

Das Folgende ist der Ausschnitt aus dem modifizierten Buildpack, das ich in meiner Firma erstellt habe:

class LanguagePack::Rails41 < LanguagePack::Rails4

  # ...

  def compile
    instrument "rails41.compile" do
      super
      allow_git do
        create_secrets_yml
      end
    end
  end

  # ...

  # writes ERB based secrets.yml for Rails 4.1+
  def create_secrets_yml
    instrument 'ruby.create_secrets_yml' do
      log("create_secrets_yml") do
        return unless File.directory?("config")
        topic("Writing config/secrets.yml to read from SECRET_KEY_BASE")
        File.open("config/secrets.yml", "w") do |file|
          file.puts <<-SECRETS_YML
<%
raise "No RACK_ENV or RAILS_ENV found" unless ENV["RAILS_ENV"] || ENV["RACK_ENV"]
%>

<%= ENV["RAILS_ENV"] || ENV["RACK_ENV"] %>:
  secret_key_base: <%= ENV["SECRET_KEY_BASE"] %>
          SECRETS_YML
        end
      end
    end
  end

  # ...

end

Sie können diesen Code natürlich erweitern, um andere Geheimnisse (z. B. API-Schlüssel von Drittanbietern usw.) hinzuzufügen, die aus Ihrer Umgebungsvariablen ausgelesen werden sollen:

...
<%= ENV["RAILS_ENV"] || ENV["RACK_ENV"] %>:
  secret_key_base: <%= ENV["SECRET_KEY_BASE"] %>
  third_party_api_key: <%= ENV["THIRD_PARTY_API"] %>

Auf diese Weise können Sie auf ganz normale Weise auf dieses Geheimnis zugreifen:

Rails.application.secrets.third_party_api_key

Stellen Sie vor dem erneuten Bereitstellen Ihrer App sicher, dass Sie zuerst Ihre Umgebungsvariable festlegen: Festlegen von SECRET_KEY_BASE im Heroku-Dashboard

Fügen Sie dann Ihr modifiziertes Buildpack (oder Sie können gerne einen Link zu meinem erstellen) zu Ihrer Heroku-App hinzu (siehe Herokus Dokumentation ) und stellen Sie Ihre App erneut bereit.

Das Buildpack erstellt Ihre config/secrets.ymlVariable automatisch als Teil des Dyno- Erstellungsprozesses aus Ihrer Umgebungsvariablen, wenn Sie git pushzu Heroku gehen.

BEARBEITEN: Herokus eigene Dokumentation schlägt vor, config/secrets.ymlaus der Umgebungsvariablen zu lesen, dies bedeutet jedoch, dass Sie diese Datei in die Quellcodeverwaltung einchecken sollten. In meinem Fall funktioniert dies nicht gut, da ich Geheimnisse für Entwicklungs- und Testumgebungen fest codiert habe, die ich lieber nicht einchecken möchte.


Die Edelsteine ​​.dotenv und .foreman sind zwar eine großartige Lösung, lösen jedoch dieses Problem: "Ich habe Geheimnisse für Entwicklungs- und Testumgebungen fest codiert". Wenn Sie diese Edelsteine ​​verwenden, benötigen Sie das Buildpack nicht, da Sie ENV_VAR in Ihrer Geheimdatei für dev und verwenden können Test auch
rmcsharry

Beachten Sie, dass Umgebungsvariablen von den meisten Infrastrukturen protokolliert werden. Dies bedeutet, dass unverschlüsselte Umgebungsvariablen in den Protokollen im Klartext angezeigt werden. Ich verwende Heroku nicht für meine Rails-Apps, habe also keine Empfehlung dafür, aber mit AWS ziehen wir verschlüsselte Werte während des Builds aus dem Build-Container aus dem Parameterspeicher und entschlüsseln sie, um diese Art von sicheren Assets zu füllen.
Daniel Nalbach

1

Sie können die geheimen Schlüssel als Umgebungsvariablen auf dem ~/.bashrcoder ~/.bash_profileIhres Servers exportieren :

export SECRET_KEY_BASE = "YOUR_SECRET_KEY"

Und dann können Sie Ihre .bashrcoder .bash_profile:

source ~/.bashrc 
source ~/.bash_profile

Verpflichte niemals deine Geheimnisse


1

In meinem Fall bestand das Problem darin, dass die config/master.keyVersionskontrolle nicht durchgeführt wurde und ich das Projekt auf einem anderen Computer erstellt hatte.

Der von Rails erstellte Standard-Gitignore schließt diese Datei aus. Da die Bereitstellung ohne diese Datei nicht möglich ist, muss sie in der Versionskontrolle sein, damit sie von jedem Computer eines Teammitglieds aus bereitgestellt werden kann.

Lösung: Entfernen Sie die config/master.keyZeile von .gitignore, schreiben Sie die Datei von dem Computer fest, auf dem das Projekt erstellt wurde, und jetzt können Sie sie git pullauf dem anderen Computer bereitstellen und von dort aus bereitstellen.

Die Leute sagen, dass einige dieser Dateien nicht der Versionskontrolle übergeben werden sollen, ohne eine alternative Lösung anzubieten. Solange Sie nicht an einem Open Source-Projekt arbeiten, sehe ich keinen Grund, nicht alles festzuschreiben, was zum Ausführen des Projekts erforderlich ist, einschließlich der Anmeldeinformationen.


Übertragen Sie niemals Ihre Hauptschlüsseldatei auf git. Dies ist eine riesige Sicherheitslücke für Ihre App. Für Open Source ist es schwierig, aber das Erstellen eines Passwort-Tresors mit Ihrem bevorzugten Passwort-Manager ist eine bessere Option.
wsizoo

Warum sollte es eine Sicherheitslücke sein, wenn das Repo privat ist? Wenn eine nicht autorisierte Person Zugriff auf mein privates Repo hat, habe ich größere Probleme als nur das Auslaufen von API-Schlüsseln. Nicht jedes Projekt ist Open Source.
Andrew Koster

Ich habe das Gefühl, dass jeder dies nur wiederholt, weil er es in einem Tutorial für ein Open-Source-Projekt gesehen hat.
Andrew Koster

Diese ganze Sache ist besonders verwirrend, weil es so viel veraltete Dokumentation über die alte secrets.ymlDatei gibt, die in den letzten Rails-Versionen veraltet war. Diese Frage zum Stapelüberlauf selbst hat eine Menge Antworten, und fast alle verwenden diese alte API.
Andrew Koster

1

Bei Rails6 hatte ich das gleiche Problem, da mir folgende Dateien fehlten. Nachdem ich sie hinzugefügt hatte, wurde das Problem behoben:

1. config/master.key
2. config/credentials.yml.enc

Stellen Sie sicher, dass Sie diese Dateien haben. !!!


0

Was ich getan habe: Auf meinem Produktionsserver erstelle ich eine Konfigurationsdatei (confthin.yml) für Thin (ich verwende sie) und füge die folgenden Informationen hinzu:

environment: production
user: www-data
group: www-data
SECRET_KEY_BASE: mysecretkeyproduction

Ich starte dann die App mit

thin start -C /whereeveristhefieonprod/configthin.yml

Arbeiten Sie wie ein Zauber und brauchen Sie dann nicht den geheimen Schlüssel für die Versionskontrolle

Ich hoffe, es könnte helfen, aber ich bin sicher, dass das Gleiche mit Unicorn und anderen gemacht werden könnte.


1
Kannst du erklären, warum / wie das funktioniert? Die Frage war für Heroku. Ist dünn eine Alternative oder ist es mit Heroku kompatibel?
Ahnbizcad

-1

Ich habe einen Patch, den ich in einer Rails 4.1-App verwendet habe, damit ich den Legacy-Schlüsselgenerator (und damit die Abwärtssitzungskompatibilität mit Rails 3) weiterhin verwenden kann, indem die secret_key_base leer bleibt.

Rails::Application.class_eval do
  # the key_generator will then use ActiveSupport::LegacyKeyGenerator.new(config.secret_token)
  fail "I'm sorry, Dave, there's no :validate_secret_key_config!" unless instance_method(:validate_secret_key_config!)
  def validate_secret_key_config! #:nodoc:
    config.secret_token = secrets.secret_token
    if config.secret_token.blank?
      raise "Missing `secret_token` for '#{Rails.env}' environment, set this value in `config/secrets.yml`"
    end 
  end 
end

Ich habe den Patch seitdem neu formatiert und als Pull-Request an Rails gesendet


-1

Ich habe eine config/initializers/secret_key.rbDatei erstellt und nur die folgende Codezeile geschrieben:

Rails.application.config.secret_key_base = ENV["SECRET_KEY_BASE"]

Aber ich denke, dass die von @Erik Trautman veröffentlichte Lösung eleganter ist;)

Edit: Oh, und schließlich habe ich diesen Rat auf Heroku gefunden: https://devcenter.heroku.com/changelog-items/426 :)

Genießen!





Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.