Je sais que je peux définir mes variables ENV dans bash via
export admin_password = "secret"
Mais existe-t-il un moyen de le faire dans mon Rails quelque part??). Ma première tentative ressemblait à ceci dans environment/development.rb
ENV['admin_password'] = "secret"
Mais ça n'a pas marché. Y a-t-il un moyen de faire cela?
[Mise à jour]
Bien que la solution sous "ancienne réponse" fonctionne pour les problèmes généraux, cette section répond à votre question après clarification de votre commentaire.
Vous devriez pouvoir définir les variables d’environnement exactement comme vous le spécifiez dans votre question. Par exemple, j'ai une application Heroku qui utilise l'authentification de base HTTP.
# app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
protect_from_forgery
before_filter :authenticate
def authenticate
authenticate_or_request_with_http_basic do |username, password|
username == ENV['HTTP_USER'] && password == ENV['HTTP_PASS']
end
end
end
# config/initializers/dev_environment.rb
unless Rails.env.production?
ENV['HTTP_USER'] = 'testuser'
ENV['HTTP_PASS'] = 'testpass'
end
Donc, dans votre cas, vous utiliseriez
unless Rails.env.production?
ENV['admin_password'] = "secret"
end
N'oubliez pas de redémarrer le serveur pour que la configuration soit rechargée!
[Ancienne réponse]
Pour une configuration à l'échelle de l'application, vous pouvez envisager une solution comme celle-ci:
Créer un fichier config/application.yml
avec une liste d’options auxquelles vous voulez pouvoir accéder:
admin_password: something_secret
allow_registration: true
facebook:
app_id: application_id_here
app_secret: application_secret_here
api_key: api_key_here
Maintenant, créez le fichier config/initializers/app_config.rb
et comprennent les éléments suivants:
require 'yaml'
yaml_data = YAML::load(ERB.new(IO.read(File.join(Rails.root, 'config', 'application.yml'))).result)
APP_CONFIG = HashWithIndifferentAccess.new(yaml_data)
Maintenant, n’importe où dans votre application, vous pouvez accéder à APP_CONFIG[:admin_password]
, avec toutes vos autres données. (Notez que puisque l’initialiseur inclut ERB.new
, votre fichier YAML peut contenir un balisage ERB.)
Ne jamais coder en dur des informations sensibles (identifiants de compte, mots de passe, etc.) . Au lieu de cela, créez un fichier pour stocker ces informations sous forme de variables d'environnement (paires clé/valeur) et excluez ce fichier de votre système de gestion de code source. Par exemple, en termes de Git (système de gestion de code source), excluez ce fichier en l’ajoutant à. gitignore:
-bash> echo '/config/app_environment_variables.rb' >> .gitignore
/config/app_environment_variables.rb
ENV['HTTP_USER'] = 'devuser'
ENV['HTTP_PASS'] = 'devpass'
Ajoutez également les lignes suivantes à /config/environment.rb
, entre la ligne require
et le Application.initialize
ligne:
# Load the app's custom environment variables here, so that they are loaded before environments/*.rb
app_environment_variables = File.join(Rails.root, 'config', 'app_environment_variables.rb')
load(app_environment_variables) if File.exists?(app_environment_variables)
C'est ça!
Comme le dit le commentaire ci-dessus, vous chargez ainsi vos variables d'environnement avant le environments/*.rb
, ce qui signifie que vous pourrez faire référence à vos variables dans ces fichiers (par exemple, environments/production.rb
). C’est un avantage considérable par rapport à l’insertion de votre fichier de variables d’environnement dans /config/initializers/
.
À l'intérieur app_environment_variables.rb
il n’est pas nécessaire de distinguer les environnements jusqu’à développement ou production car vous ne pourrez jamais valider ce fichier dans votre système de gestion de code source; le développement contexte par défaut. Mais si vous devez définir quelque chose de spécial pour l'environnement test (ou pour les occasions où vous testez production mode localement) , ajoutez juste un bloc conditionnel ci-dessous toutes les autres variables:
if Rails.env.test?
ENV['HTTP_USER'] = 'testuser'
ENV['HTTP_PASS'] = 'testpass'
end
if Rails.env.production?
ENV['HTTP_USER'] = 'produser'
ENV['HTTP_PASS'] = 'prodpass'
end
Chaque fois que vous mettez à jour app_environment_variables.rb
, redémarrez le serveur d'applications. En supposant que vous utilisez les goûts de Apache/Passenger ou Rails server
:
-bash> touch tmp/restart.txt
Dans votre code, reportez-vous aux variables d'environnement comme suit:
def authenticate
authenticate_or_request_with_http_basic do |username, password|
username == ENV['HTTP_USER'] && password == ENV['HTTP_PASS']
end
end
Notez que l'intérieur app_environment_variables.rb
vous devez spécifier booleans et nombres comme chaînes (par exemple ENV['SEND_MAIL'] = 'false'
_ pas seulement false
, et ENV['TIMEOUT'] = '30'
pas seulement 30
), sinon vous obtiendrez les erreurs can't convert false into String
et can't convert Fixnum into String
, respectivement.
Stocker et partager des informations sensibles
Le dernier nœud à nouer est le suivant: Comment partager ces informations sensibles avec vos clients et/ou partenaires? Aux fins de la continuité des activités (lorsque vous êtes frappé par une étoile filante, comment clients et/ou partenaires reprennent-ils toutes les opérations du site?), vos clients et/ou partenaires doivent connaître toutes les informations d'identification requises par votre application. L'envoi de courriels/skypes n'est pas sécurisé et conduit au désarroi. Le stocker dans Google Docs partagés n'est pas mauvais (si tout le monde utilise https), mais une application dédiée au stockage et au partage de petits titres comme les mots de passe serait idéale.
Comment définir des variables d'environnement sur Heroku
Si vous avez un seul environnement sur Heroku:
-bash> heroku config:add HTTP_USER='herouser'
-bash> heroku config:add HTTP_USER='heropass'
Si vous avez plusieurs environnements sur Heroku:
-bash> heroku config:add HTTP_USER='staguser' --remote staging
-bash> heroku config:add HTTP_PASS='stagpass' --remote staging
-bash> heroku config:add HTTP_USER='produser' --remote production
-bash> heroku config:add HTTP_PASS='prodpass' --remote production
Contremaître et .env
De nombreux développeurs utilisent Foreman (installé avec le Heroku Toolbelt ) à exécutent leurs applications localement (au lieu d'utiliser Apache/Passenger ou Rails server
). Foreman et Heroku utilisent Procfile
pour déclarer les commandes exécutées par votre application , la transition du développement local vers Heroku est donc transparente. J'utilise Foreman et Heroku dans chaque Rails projet, cette commodité est donc excellente. Mais voici la chose .. Foreman charge les variables d'environnement stockées dans /.env
via dotenv mais malheureusement dotenv n’analyse que le fichier pour key=value
_ paires ; ces paires ne deviennent pas des variables sur-le-champ, vous ne pouvez donc pas vous référer à des variables déjà définies (pour garder les choses sèches), vous ne pouvez pas non plus faire "Ruby" (comme indiqué ci-dessus avec les conditions), ce que vous pouvez faire. faire à /config/app_environment_variables.rb
. Par exemple, pour garder les choses DRY), je fais parfois des choses comme celle-ci:
ENV['SUPPORT_EMAIL']='Company Support <[email protected]>'
ENV['MAILER_DEFAULT_FROM'] = ENV['SUPPORT_EMAIL']
ENV['MAILER_DEFAULT_TO'] = ENV['SUPPORT_EMAIL']
J'utilise donc Foreman pour exécuter mes applications localement, mais je n'utilise pas son .env
fichier pour le chargement des variables d’environnement; j'utilise plutôt Foreman en conjonction avec le /config/app_environment_variables.rb
approche décrite ci-dessus.
La façon dont je tente de le faire dans ma question fonctionne réellement!
# environment/development.rb
ENV['admin_password'] = "secret"
Je viens de redémarrer le serveur. Je pensais courir reload!
in Rails serait suffisante mais je devais également redémarrer le serveur Web.
Je choisis ma propre réponse car j'estime qu'il s'agit d'un meilleur endroit pour définir et définir les variables ENV.
Outre les solutions proposées, il existe des alternatives plus propres si vous utilisez certains serveurs de développement.
Avec Heroku Foreman , vous pouvez créer des variables d'environnement par projet dans un .env
fichier:
ADMIN_PASSOWRD="secret"
Avec Pow , vous pouvez utiliser un .powenv
fichier:
export ADMIN_PASSOWRD="secret"
Je pense que le meilleur moyen est de les stocker dans un fichier yml, puis de charger ce fichier en utilisant cette commande dans le fichier intializer
APP_CONFIG = YAML.load_file("#{Rails.root}/config/CONFIG.yml")[Rails.env].to_hash
vous pouvez facilement accéder aux variables de configuration liées à l'environnement.
Votre structure de valeur de clé de fichier Yml:
development:
app_key: 'abc'
app_secret: 'abc'
production:
app_key: 'xyz'
app_secret: 'ghq'
L'environnement système et l'environnement de Rails sont des choses différentes. ENV
vous permet de travailler avec l'environnement de Rails, mais si vous voulez changer l'environnement du système au moment de l'exécution, vous pouvez simplement entourer la commande de backticks.
# Ruby code
`export admin_password="secret"`
# more Ruby code
Script de chargement du fichier personnalisé .env
: Ajoutez les lignes suivantes à /config/environment.rb
, Entre la ligne require
et la ligne Application.initialize
:
# Load the app's custom environment variables here, so that they are loaded before environments/*.rb
app_environment_variables = File.join(Rails.root, 'config', 'local_environment.env')
if File.exists?(app_environment_variables)
lines = File.readlines(app_environment_variables)
lines.each do |line|
line.chomp!
next if line.empty? or line[0] == '#'
parts = line.partition '='
raise "Wrong line: #{line} in #{app_environment_variables}" if parts.last.empty?
ENV[parts.first] = parts.last
end
end
Et config/local_environment.env
(Vous voudrez qu'il .gitignore
) Ressemble à ceci:
# This is ignored comment
DATABASE_URL=mysql2://user:[email protected]:3307/database
RACK_ENV=development
(Basé sur la solution de @ user664833)