是否有可能在我的代码中为rails开发环境设置ENVvariables?

我知道我可以通过bash设置我的ENVvariables

export admin_password = "secret" 

但有没有办法在我的rails源代码中执行它? 我的第一次尝试是在这样的environment/development.rb

 ENV['admin_password'] = "secret" 

但它没有工作。 有没有办法做到这一点?

[更新]

虽然“旧答案”下的解决scheme适用于一般问题,但本部分将在您的评论澄清后回答您的具体问题。

你应该可以像你在问题中指定的一样设置环境variables。 作为一个例子,我有一个使用HTTP基本authentication的Heroku应用程序。

 # 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 

所以在你的情况下,你会使用

 unless Rails.env.production? ENV['admin_password'] = "secret" end 

不要忘记重新启动服务器,以便重新加载configuration!

[老问答]

对于应用程序范围的configuration,您可以考虑如下的解决scheme:

创build一个文件config/application.yml其中包含您希望能够访问的选项:

 admin_password: something_secret allow_registration: true facebook: app_id: application_id_here app_secret: application_secret_here api_key: api_key_here 

现在,创build文件config/initializers/app_config.rb并包含以下内容:

 require 'yaml' yaml_data = YAML::load(ERB.new(IO.read(File.join(Rails.root, 'config', 'application.yml'))).result) APP_CONFIG = HashWithIndifferentAccess.new(yaml_data) 

现在,在您的应用程序的任何地方,您都可以访问APP_CONFIG[:admin_password]以及所有其他数据。 (请注意,由于初始化程序包含ERB.new ,因此您的YAML文件可以包含ERB标记。)

不要硬编码敏感信息(帐户凭证,密码等) 。 相反,创build一个文件来存储这些信息作为环境variables(键/值对),并从源代码pipe理系统中排除该文件。 例如,就Git(源代码pipe理系统)而言,通过添加它来排除该文件。 gitignore

 -bash> echo '/config/app_environment_variables.rb' >> .gitignore 

/config/app_environment_variables.rb

 ENV['HTTP_USER'] = 'devuser' ENV['HTTP_PASS'] = 'devpass' 

同样, /config/environment.rb下行添加到/config/environment.rb ,在require行和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', 'app_environment_variables.rb') load(app_environment_variables) if File.exists?(app_environment_variables) 

而已!

正如上面的注释所说,通过这样做,您将在environments/*.rb之前加载您的环境variables,这意味着您将能够在这些文件内引用您的variables(例如environments/production.rb )。 把你的环境variables文件放在/config/initializers/里面是一个很大的优势。

app_environment_variables.rb里面,不需要区分开发环境和生产环境,因为你永远不会把这个文件提交到你的源代码pipe理系统,因此默认情况下是用于开发环境。 但是如果你需要为testing环境设置一些特殊的东西(或者在本地testing生产模式的场合),只需要所有其他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 

无论何时更新app_environment_variables.rb ,请重新启动应用程序服务器。 假设你使用的是Apache / Passenger或者rails server

 -bash> touch tmp/restart.txt 

在你的代码中,参考如下的环境variables:

 def authenticate authenticate_or_request_with_http_basic do |username, password| username == ENV['HTTP_USER'] && password == ENV['HTTP_PASS'] end end 

请注意,在app_environment_variables.rb您必须指定布尔值数字作为string (例如ENV['SEND_MAIL'] = 'false'不只是false ,而ENV['TIMEOUT'] = '30' ENV['SEND_MAIL'] = 'false' ENV['TIMEOUT'] = '30'不只是30 ),否则您将获得错误can't convert false into Stringcan't convert Fixnum into String

存储和共享敏感信息

最后的结局是: 如何与客户和/或合作伙伴分享这些敏感信息? 为了实现业务连续性(例如,当您受到meteor影响,您的客户和/或合作伙伴如何恢复网站的全面运营?),您的客户和/或合作伙伴需要知道您的应用所需的所有凭据。 通过电子邮件发送/将这些事情拖到空中是不安全的,并导致混乱。 将其存储在共享的Google文档中并不差(如果每个人都使用https),但专门用于存储和共享密码等应用程序的应用程序将是理想select。

如何在Heroku上设置环境variables

如果你在Heroku上有一个单一的环境:

 -bash> heroku config:add HTTP_USER='herouser' -bash> heroku config:add HTTP_USER='heropass' 

如果你在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 

工头和.env

许多开发人员使用Foreman (与Heroku Toolbelt一起安装)在本地运行应用程序 (而不是使用Apache / Passenger或rails server )。 Foreman和Heroku使用Procfile来声明你的应用程序运行了什么命令 ,所以从本地开发到Heroku的过渡在这方面是无缝的。 我在每个Rails项目中都使用Foreman和Heroku,所以这个方便性非常好。 但是这里的东西.. 工头加载通过dotenv存储在/.env环境variables,但不幸的是dotenv本质上只parsing文件的key=value对 ; 那些对在这里不会变成variables,所以你不能引用已经设置好的variables(保持干燥),也不能在那里做“Ruby”(如上面的条件所述),你可以在/config/app_environment_variables.rb 。 例如,在保持干爽的方面,我有时会做这样的事情:

 ENV['SUPPORT_EMAIL']='Company Support <support@company.com>' ENV['MAILER_DEFAULT_FROM'] = ENV['SUPPORT_EMAIL'] ENV['MAILER_DEFAULT_TO'] = ENV['SUPPORT_EMAIL'] 

因此,我使用Foreman在本地运行我的应用程序,但是我不使用它的.env文件来加载环境variables; 相反,我将Foreman与上述的/config/app_environment_variables.rb方法结合使用。

除了这里的解决scheme外,如果您使用某些开发服务器,还有更清晰的替代scheme。

使用Heroku的工头 ,您可以在.env文件中创build每个项目的环境variables:

 ADMIN_PASSOWRD="secret" 

使用Pow ,你可以使用.powenv文件:

 export ADMIN_PASSOWRD="secret" 

我试图在我的问题中这样做的方式实际上是有效的!

 # environment/development.rb ENV['admin_password'] = "secret" 

我只需要重新启动服务器。 我想运行reload! 在轨道控制台将是足够的,但我也不得不重新启动Web服务器。

我select自己的答案,因为我觉得这是一个更好的地方放置和设置ENVvariables

我认为最好的方法是将它们存储在某个yml文件中,然后使用intializer文件中的该命令加载该文件

 APP_CONFIG = YAML.load_file("#{Rails.root}/config/CONFIG.yml")[Rails.env].to_hash 

您可以轻松访问环境相关的configurationvariables。

你的Yml文件键值结构:

 development: app_key: 'abc' app_secret: 'abc' production: app_key: 'xyz' app_secret: 'ghq' 

系统环境和rails的环境是不同的东西。 ENV让你使用rails的环境,但是如果你想要做的是在运行时改变系统的环境,你可以用反引号包围命令。

 # ruby code `export admin_password="secret"` # more ruby code 

加载自定义.env文件的脚本: .env添加到/config/environment.rb ,位于require行和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 

config/local_environment.env (你会想.gitignore它)看起来像:

 # This is ignored comment DATABASE_URL=mysql2://user:psw@0.0.0:3307/database RACK_ENV=development 

(基于@ user664833的解决scheme)