J’ai créé une application de rails (rails 4.1) à partir de zéro et je suis confronté à un problème étrange que je ne suis pas en mesure de résoudre.
Chaque fois que j’essaie de déployer mon application sur Heroku, je reçois une erreur 500:
Missing
secret_key_base
pour l’environnement de production, définissez cette valeur dansconfig/secrets.yml
Le fichier secret.yml contient la configuration suivante:
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 est-ce que je reçois toujours cette erreur?
Merci beaucoup
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 suis connecté au serveur de production et j’ai réalisé un mini guide des étapes 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é la façon de gérer la clé secrète, donc si vous lisez le fichier exampleRailsProject/config/secrets.yml
situé à exampleRailsProject/config/secrets.yml
vous trouverez quelque chose comme ceci:
# 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 secret_key_base
dans votre serveur de production. Pour résoudre cette erreur, vous devez suivre ces étapes pour créer une variable d’environnement pour Linux (dans mon cas Ubuntu) sur votre serveur de production:
Dans le terminal de votre serveur de production, exécutez la commande suivante:
$ RAILS_ENV=production rake secret
Cela retourne une grande chaîne avec des lettres et des chiffres, copiez-la (nous ferons référence à ce code comme GENERATED_CODE).
Connectez-vous à votre serveur
Si vous vous connectez en tant qu’utilisateur root, recherchez ce fichier et modifiez-le:
$ vi /etc/profile
Aller au bas du fichier (“SHIFT + G” pour la majuscule G dans VI)
Ecrivez votre variable d’environnement avec le GENERATED_CODE (Appuyez sur la touche “i” pour écrire dans 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 (nous appuyons sur la touche “Echap” puis écrivez “: x” et “ENTER” pour enregistrer et quitter dans VI).
Mais si vous vous connectez en tant qu’utilisateur normal, appelons-le “exemple_utilisateur” pour cet aperçu, vous devrez trouver l’un de ces autres fichiers:
$ vi ~/.bash_profile $ vi ~/.bash_login $ vi ~/.profile
Ces fichiers sont en 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
vous devrez écrire uniquement 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 la majuscule G dans VI).
Et nous allons écrire notre variable d’environnement avec notre GENERATED_CODE (Appuyez sur la touche “i” pour écrire dans 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, sauvegardez les modifications et fermez le fichier (nous appuyons sur la touche “ESC” puis écrivez “: x” et “ENTER” pour enregistrer et quitter dans VI).
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é, vous verrez le GENERATED_CODE d’avant. 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 vous reconnectez au serveur de production, vous aurez cette variable d’environnement définie et prête à l’utiliser.
Et c’est tout!! J’espère que ce mini guide vous aidera à résoudre cette erreur.
Disclaimer: Je ne suis pas un gourou de Linux ou Rails, donc si vous trouvez quelque chose qui ne va pas ou une erreur, je serai ravi de le réparer!
Je vais supposer que vos fichiers .gitignore
ne sont pas entrés dans le contrôle de code source (c.-à-d. .gitignore
dans le fichier .gitignore
). Même si ce n’est pas votre cas, c’est ce que de nombreuses autres personnes qui consultent cette question ont fait car elles ont exposé leur code sur Github et ne veulent pas que leur clé secrète flotte.
Si ce n’est pas le cas, 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 vérifiant le fichier secrets.yml
qui n’existe pas. La solution simple consiste à aller dans votre fichier config/environments/production.rb
et à append 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.
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 le même problème et il s’est avéré que le .gitignore
Github créé pour mon application Rails comprenait config/secrets.yml
.
Cela a fonctionné pour moi.
SSH dans votre serveur de production et cd
dans votre répertoire actuel, exécutez un bundle exec rake secret
rake secret
ou un rake secret
, vous obtiendrez une longue chaîne en tant que sortie, copiez cette chaîne.
Maintenant, lancez sudo nano /etc/environment
.
Coller en bas du fichier
export SECRET_KEY_BASE=rake secret ruby -e 'p ENV["SECRET_KEY_BASE"]'
Où rake secret
est la chaîne que vous venez de copier, collez cette chaîne copiée à la place du rake secret
.
Redémarrez le serveur et testez en exécutant echo $SECRET_KEY_BASE
.
Bien que vous puissiez utiliser les initialiseurs comme les autres réponses, la méthode conventionnelle Rails 4.1+ consiste à utiliser config/secrets.yml
. La raison pour laquelle l’équipe Rails a introduit ceci est hors de la scope de cette réponse mais la TL; DR est que secret_token.rb
confond la configuration et le code tout en étant un risque de sécurité puisque le jeton est archivé dans l’historique de contrôle source et le seul système qui a besoin de connaître le jeton secret de production est l’infrastructure de production.
Vous devriez append ce fichier à .gitignore
même manière que vous n’appendiez 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 pour Ruby , j’ai fini par falsifier leur repo et l’ai modifié pour créer config/secrets.yml
SECRETS_KEY_BASE
partir de la variable d’environnement SECRETS_KEY_BASE
.
Depuis que cette fonctionnalité a été introduite dans Rails 4.1, j’ai jugé bon d’éditer ./lib/language_pack/rails41.rb
et d’append cette fonctionnalité.
Ce qui suit est l’ extrait du buildpack modifié que j’ai créé chez moi:
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 append d’autres secrets (par exemple, des clés d’API tierces, etc.) à lire dans votre 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, assurez-vous de définir d’abord votre variable d’environnement:
Ajoutez ensuite votre buildpack modifié (ou vous êtes plus que bienvenu pour créer un lien vers le mien) vers votre application Heroku (voir la documentation de Heroku) 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 lancez une git push
vers Heroku.
EDIT: La propre documentation de Heroku suggère de créer config/secrets.yml
pour lire la variable d’environnement, mais cela implique que vous devriez vérifier ce fichier dans le contrôle de code source. Dans mon cas, cela ne fonctionne pas bien car j’ai des secrets codés pour les environnements de développement et de test que je préfère ne pas enregistrer.
Vous pouvez exporter les clés secrètes en tant que variables d’environnement sur les ~/.bashrc
ou ~/.bash_profile
de votre serveur:
export SECRET_KEY_BASE = "YOUR_SECRET_KEY"
Et puis, vous pouvez vous .bashrc
votre .bash_profile
.bashrc
ou .bash_profile
:
source ~/.bashrc source ~/.bash_profile
Ne jamais commettre vos secrets.yml
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 j’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
Travailler comme un charme et pas besoin d’avoir la clé secrète sur 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.
J’ai un patch 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 la compatibilité de session en arrière avec Rails 3), en permettant à la base secret_key d’ê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
Je l’ai depuis reformaté le patch est soumis à Rails comme une demande de traction
J’ai créé le fichier config/initializers/secret_key.rb
et j’ai écrit uniquement la ligne de code suivante:
Rails.application.config.secret_key_base = ENV["SECRET_KEY_BASE"]
Mais je pense que la solution publié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!
cela fonctionne bien https://gist.github.com/pablosalgadom/4d75f30517edc6230a67 pour l’utilisateur root devrait modifier
$ /etc/profile
mais si vous n’êtes pas root, vous devez mettre le code généré dans ce qui suit
$ ~/.bash_profile $ ~/.bash_login $ ~/.profile
Sur Nginx / Passenger / Ruby (2.4) / Rails (5.1.1), rien 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
La réponse de Demi Magus a fonctionné pour moi jusqu’à ce que Rails 5.
Sur Apache2 / Passenger / Ruby (2.4) / Rails (5.1.6), j’ai dû mettre
export SECRET_KEY_BASE=GENERATED_CODE
de Demi Magus répond dans / etc / apache2 / envvars, car / etc / profile semble être ignoré.
Source: https://www.phusionpassenger.com/library/indepth/environment_variables.html#apache
J’ai eu le même problème après avoir utilisé le fichier .gitignore de https://github.com/github/gitignore/blob/master/Rails.gitignore
Tout s’est bien passé après avoir commenté les lignes suivantes dans le fichier .gitignore.
config/initializers/secret_token.rb config/secrets.yml