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 dansconfig/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
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:
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).
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).
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!
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.
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
.
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"]'
Où 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
.
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:
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.
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
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!
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.
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
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
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
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
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.