web-dev-qa-db-fra.com

Comment résoudre l'erreur "Manque` secret_key_base` pour l'environnement 'de production' "(Rails 4.1)

J'ai créé une application Rails (Rails 4.1) à partir de zéro et je suis confronté à un problème étrange que je ne parviens pas à résoudre.

Chaque fois que j'essaie de déployer mon application sur Heroku, le code d'erreur 500 s'affiche:

Manquant secret_key_base pour l'environnement 'de production', définissez cette valeur dans config/secrets.yml

Le fichier secret.yml contient la configuration suivante:

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

Sur Heroku, j'ai configuré une variable d'environnement "SECRET_KEY_BASE" avec le résultat de la commande "rake secret". Si je lance "heroku config", je peux voir la variable avec le nom et la valeur corrects.

Pourquoi ai-je toujours cette erreur?

Merci beaucoup

158
Paolo Laurenti

J'ai eu le même problème et je l'ai résolu en créant une variable d'environnement à charger chaque fois que je me connectais au serveur de production et que je réalisais un mini guide des étapes à suivre pour le configurer:

https://Gist.github.com/pablosalgadom/4d75f30517edc6230a67

J'utilisais Rails 4.1 avec Unicorn v4.8.2, lorsque j'ai essayé de déployer mon application, elle n'a pas démarré correctement et dans le fichier Unicorn.log, j'ai trouvé ce message d'erreur:

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

Après quelques recherches, j'ai découvert que Rails 4.1 avait changé le mode de gestion de la clé secret_key. Si vous lisez le fichier secrets.yml situé à l'adresse exampleRailsProject/config/secrets.yml, vous obtiendrez un résultat similaire à celui-ci:

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

Cela signifie que Rails vous recommande d’utiliser une variable d’environnement pour le secret_key_base de votre serveur de production. Pour résoudre cette erreur, vous devez suivre ces étapes afin de créer une variable d’environnement pour Linux Ubuntu) dans votre serveur de production:

  1. Dans le terminal de votre serveur de production, exécutez la commande suivante:

    $ Rails_ENV=production rake secret
    

    Ceci retourne une grande chaîne avec des lettres et des chiffres, copiez-le (nous nous référerons à ce code en tant que GENERATED_CODE).

  2. Connectez-vous à votre serveur

    • Si vous vous connectez en tant qu'utilisateur root, trouvez ce fichier et modifiez-le:

      $ vi /etc/profile
      

      Aller au bas du fichier ("MAJ + G" pour la majuscule G dans VI)

      Ecrivez votre variable d’environnement avec GENERATED_CODE (appuyez sur la touche "i" pour écrire dans le VI), assurez-vous d’être dans une nouvelle ligne à la fin du fichier:

      $ export SECRET_KEY_BASE=GENERATED_CODE
      

      Enregistrez les modifications et fermez le fichier (appuyez sur la touche "ESC" puis écrivez les touches ": x" et "ENTER" pour enregistrer et quitter le VI).

    • Mais si vous vous connectez en tant qu'utilisateur normal, appelons-le "exemple_utilisateur" pour ce Gist, vous devrez trouver l'un de ces autres fichiers:

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

      Ces fichiers sont par ordre d'importance, ce qui signifie que si vous avez le premier fichier, vous n'avez pas besoin d'écrire dans les autres. Donc si vous avez trouvé ces 2 fichiers dans votre répertoire ~/.bash_profile et ~/.profile, il vous suffira d'écrire dans le premier ~/.bash_profile, car Linux ne lira que celui-ci et l'autre sera ignoré .

      Ensuite, nous allons au bas du fichier ("SHIFT + G" pour le capital G dans VI).

      Et nous écrirons notre variable d’environnement avec notre GENERATED_CODE (Appuyez sur la touche "i" pour écrire en VI), assurez-vous d’être dans une nouvelle ligne à la fin du fichier:

      $ export SECRET_KEY_BASE=GENERATED_CODE
      

      Après avoir écrit le code, enregistrez les modifications et fermez le fichier (appuyez sur la touche "ESC" puis écrivez les touches ": x" et "ENTER" pour enregistrer et quitter le VI).

  3. Vous pouvez vérifier que notre variable d’environnement est correctement définie sous Linux avec cette commande:

    $ printenv | grep SECRET_KEY_BASE
    

    ou avec:

    $ echo $SECRET_KEY_BASE
    

    Lorsque vous exécutez cette commande, si tout s'est bien passé, le code GENERATED_CODE précédent s'affiche. Enfin, avec toute la configuration effectuée, vous devriez pouvoir déployer sans problème votre application Rails avec Unicorn ou autre.

Lorsque vous fermez votre terminal Shell et que vous vous reconnectez au serveur de production, cette variable d'environnement est définie et prête à être utilisée.

Et c'est tout!! J'espère que ce mini-guide vous aidera à résoudre cette erreur.

Disclaimer: Je ne suis pas un gourou Linux ou Rails, donc si vous trouvez quelque chose qui ne va pas ou une erreur, je serai ravi de le réparer!

201
Demi Magus

Je suppose que votre secrets.yml n'a pas été enregistré dans le contrôle de source (c'est-à-dire qu'il se trouve dans le fichier .gitignore). Même si ce n'est pas votre cas, c'est ce que beaucoup d'autres personnes qui consultent cette question ont fait parce que leur code est exposé sur Github et qu'elles ne veulent pas que leur clé secrète flotte.

Si ce n'est pas dans le contrôle de source, Heroku ne le sait pas. Donc, Rails recherche Rails.application.secrets.secret_key_base et il n'a pas été défini car Rails le définit en consultant le fichier secrets.yml qui n'existe pas. La solution de contournement simple consiste à entrer dans votre fichier config/environments/production.rb et à ajouter la ligne suivante:

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

Cela indique à votre application de définir la clé secrète à l'aide de la variable d'environnement au lieu de la rechercher dans secrets.yml. Cela m'aurait épargné beaucoup de temps pour le savoir d'avance.

81
Erik Trautman

Ajoutez config/secrets.yml au contrôle de version et déployez à nouveau. Vous devrez peut-être supprimer une ligne de .gitignore pour pouvoir valider le fichier.

J'ai eu exactement ce même problème et il s'est avéré que le passe-partout .gitignore Github créé pour mon Rails application incluse config/secrets.yml.

55
danielricecodes

Cela a fonctionné pour moi.

SSH sur votre serveur de production et cd dans votre répertoire actuel, exécutez bundle exec rake secret ou rake secret, vous obtiendrez une longue chaîne en sortie, copiez cette chaîne.

Maintenant, lancez Sudo nano /etc/environment.

Coller au bas du fichier

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

rake secret est la chaîne que vous venez de copier, collez cette chaîne copiée à la place de rake secret.

Redémarrez le serveur et testez en exécutant echo $SECRET_KEY_BASE.

12
sumitsv21

Bien que vous puissiez utiliser les initialiseurs comme les autres réponses, la méthode conventionnelle Rails 4.1+ consiste à utiliser le config/secrets.yml. La raison pour laquelle l'équipe Rails a introduit ceci est au-delà de la portée de cette réponse, mais le TL; DR est que secret_token.rb confond la configuration et le code tout en constituant un risque pour la sécurité puisque le jeton est vérifié. L’infrastructure de production est l’historique de contrôle des sources et le seul système qui doit connaître le jeton secret de production.

Vous devez ajouter ce fichier à .gitignore de la même manière que vous n’ajouteriez pas config/database.yml au contrôle de source.

En référençant le propre code de Heroku pour configurer config/database.yml à partir de DATABASE_URL dans leur Buildpack for Ruby , j'ai fini forçant leur repo et l'a modifié pour créer config/secrets.yml de SECRETS_KEY_BASE variable d'environnement.

Depuis que cette fonctionnalité a été introduite dans Rails 4.1, j’ai pensé qu’il était approprié de modifier ./lib/language_pack/Rails41.rb et d’ajouter cette fonctionnalité.

Voici le extrait du buildpack modifié que j'ai créé dans mon entreprise:

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

Vous pouvez bien sûr étendre ce code pour ajouter d’autres secrets (par exemple, des clés d’API tierces, etc.) à lire dans la variable d’environnement:

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

De cette façon, vous pouvez accéder à ce secret de manière très standard:

Rails.application.secrets.third_party_api_key

Avant de redéployer votre application, veillez à définir d'abord la variable d'environnement: Setting SECRET_KEY_BASE in Heroku Dashboard

Ajoutez ensuite votre buildpack modifié (ou vous êtes plus que bienvenu pour créer un lien vers le mien) à votre application Heroku (voir Heroku's documentation ) et redéployez votre application.

Le buildpack créera automatiquement votre config/secrets.yml à partir de votre variable d’environnement dans le cadre du processus de génération de dyno chaque fois que vous git Push à Heroku.

EDIT: Heroku's documentation suggère de créer config/secrets.yml pour lire à partir de la variable d’environnement, mais cela implique que vous deviez vérifier ce fichier dans le contrôle de source. Dans mon cas, cela ne fonctionne pas bien car j'ai des secrets codés en dur pour les environnements de développement et de test que je préférerais ne pas enregistrer.

3
stackunderflow

Vous pouvez exporter les clés secrètes sous forme de variables d’environnement sur le ~/.bashrc ou ~/.bash_profile de votre serveur:

export SECRET_KEY_BASE = "YOUR_SECRET_KEY"

Et ensuite, vous pouvez utiliser votre source .bashrc ou .bash_profile:

source ~/.bashrc 
source ~/.bash_profile

Ne commettez jamais vos secrets.yml

1
alessandrocb

J'ai créé le fichier config/initializers/secret_key.rb et je n'ai écrit que la ligne de code suivante:

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

Mais je pense que cette solution postée par @ Erik Trautman est plus élégante;)

Edit: Oh, et finalement j'ai trouvé ce conseil sur Heroku: https://devcenter.heroku.com/changelog-items/426 :)

Prendre plaisir!

0
fadehelix

Dans mon cas, le problème était que config/master.key n'était pas sous contrôle de version et que j'avais créé le projet sur un autre ordinateur.

Le fichier .gitignore par défaut créé par Rails exclut ce fichier. Étant donné qu'il est impossible de déployer sans ce fichier, il doit être sous contrôle de version afin de pouvoir se déployer à partir de l'ordinateur de n'importe quel membre de l'équipe.

Solution: supprimez la ligne config/master.key de .gitignore, validez le fichier à partir de l'ordinateur sur lequel le projet a été créé. Vous pouvez maintenant git pull sur l'autre ordinateur et le déployer.

Les gens disent de ne pas envoyer certains de ces fichiers dans le contrôle de version, sans offrir de solution alternative. Tant que vous ne travaillez pas sur un projet open source, je ne vois aucune raison de ne pas engager tout ce qui est nécessaire pour exécuter le projet, y compris les informations d'identification.

0
Andrew Koster

Sur Nginx/Passenger/Ruby (2.4)/Rails (5.1.1), rien d’autre n’a fonctionné sauf:

passenger_env_var dans /etc/nginx/sites-available/default dans le bloc serveur.

Source: https://www.phusionpassenger.com/library/config/nginx/reference/#passenger_env_var

0
Kasperi

cela fonctionne bien https://Gist.github.com/pablosalgadom/4d75f30517edc6230a67 pour l'utilisateur root doit éditer

$ /etc/profile

mais si vous êtes non root, mettez le code généré dans ce qui suit

$ ~/.bash_profile

$ ~/.bash_login

$ ~/.profile
0
bung_firman

La réponse de Demi Magus a fonctionné pour moi jusqu’à Rails 5.

Sur Apache2/Passenger/Ruby (2.4)/Rails (5.1.6), je devais mettre

export SECRET_KEY_BASE=GENERATED_CODE

de Demi Magus répondre dans/etc/Apache2/envvars, car/etc/profile semble être ignoré.

Source: https://www.phusionpassenger.com/library/indepth/environment_variables.html#Apache

0
Florent L.

J'ai un correctif que j'ai utilisé dans une application Rails 4.1 pour me permettre de continuer à utiliser le générateur de clé hérité (et donc une compatibilité de session en amont avec Rails 3), en autorisant le secret_key_base être vide.

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

J'ai depuis reformaté le patch soumis à Rails en tant que requête d'extraction

0
BF4

Ce que j'ai fait: Sur mon serveur de production, je crée un fichier de configuration (confthin.yml) pour Thin (je l'utilise) et ajoute les informations suivantes:

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

Je lance ensuite l'application avec

thin start -C /whereeveristhefieonprod/configthin.yml

Travaillez comme un charme sans avoir besoin de la clé secrète pour le contrôle de version

J'espère que cela pourrait aider, mais je suis sûr que la même chose pourrait être faite avec Unicorn et d'autres.

0