在开发中使用 Shim 将环境变量从.env
加载到ENV
中。
在环境中存储配置是十二要素应用程序的原则之一。部署环境之间可能发生变化的任何内容(例如数据库的资源句柄或外部服务的凭据)都应从代码中提取到环境变量中。
但在运行多个项目的开发机器或持续集成服务器上设置环境变量并不总是可行的。当环境引导时,dotenv 将变量从.env
文件加载到ENV
中。
将此行添加到应用程序 Gemfile 的顶部并运行bundle install
:
gem 'dotenv' , groups : [ :development , :test ]
将应用程序配置添加到项目根目录下的.env
文件中:
S3_BUCKET=YOURS3BUCKET
SECRET_KEY=YOURSECRETKEYGOESHERE
每当您的应用程序加载时,这些变量都将在ENV
中可用:
config . fog_directory = ENV [ 'S3_BUCKET' ]
请参阅 API 文档了解更多信息。
Dotenv 将在 Rails 应用程序启动时自动加载。请参阅自定义 Rails 以更改加载哪些文件以及何时加载。
在应用程序引导过程中尽早加载 Dotenv:
require 'dotenv/load'
# or
require 'dotenv'
Dotenv . load
默认情况下, load
将在当前工作目录中查找名为.env
的文件。传入多个文件,它们将按顺序加载。为变量设置的第一个值将获胜。
require 'dotenv'
Dotenv . load ( 'file1.env' , 'file2.env' )
从 3.0 开始,Rails 应用程序中的 dotenv 将在每次测试后自动恢复ENV
。这意味着您可以在测试中修改ENV
,而不必担心将状态泄漏给其他测试。它适用于ActiveSupport::TestCase
和Rspec
。
要禁用此行为,请在config/application.rb
或config/environments/test.rb
中设置config.dotenv.autorestore = false
。如果您的应用程序使用climate_control或ice_age,则默认情况下禁用它。
要在 Rails 应用程序之外使用此行为,只需在测试套件中require "dotenv/autorestore"
。
有关手动使用,请参阅Dotenv.save
、 Dotenv.restore 和Dotenv.modify(hash) { ... }
。
为了确保.env
加载到 rake 中,请加载任务:
require 'dotenv/tasks'
task mytask : :dotenv do
# things that require .env
end
您可以在启动应用程序之前使用dotenv
可执行文件 load .env
:
$ dotenv ./script.rb
dotenv
可执行文件还接受标志-f
。它的值应该是一个以逗号分隔的配置文件列表,按最重要到最不重要的顺序排列。所有文件都必须存在。标志与其值之间必须有一个空格。
$ dotenv -f " .env.local,.env " ./script.rb
dotenv
可执行文件可以选择使用-i
或--ignore
标志忽略丢失的文件。例如,如果.env.local
文件不存在,则以下命令将忽略丢失的文件并仅加载.env
文件。
$ dotenv -i -f " .env.local,.env " ./script.rb
如果您使用的 gem 需要在加载之前设置环境变量,则在Gemfile
中将dotenv
列在其他 gem 之前,并需要dotenv/load
。
gem 'dotenv' , require : 'dotenv/load'
gem 'gem-that-requires-env-variables'
Dotenv 将根据RAILS_ENV
加载以下文件,第一个文件具有最高优先级, .env
具有最低优先级:
优先事项 | 环境 | .gitignore 吗? | 笔记 | ||
---|---|---|---|---|---|
发展 | 测试 | 生产 | |||
最高 | .env.development.local | .env.test.local | .env.production.local | 是的 | 环境特定的本地覆盖 |
第二名 | .env.local | 不适用 | .env.local | 是的 | 本地覆盖 |
第三名 | .env.development | .env.test | .env.production | 不 | 共享环境特定变量 |
最后的 | .env | .env | .env | 或许 | 为所有环境共享 |
这些文件在before_configuration
回调期间加载,当在config/application.rb
中使用class Application < Rails::Application
定义Application
常量时会触发该回调。如果您需要更快地初始化,或者需要自定义加载过程,可以在application.rb
的顶部进行
# config/application.rb
Bundler . require ( * Rails . groups )
# Load .env.local in test
Dotenv :: Rails . files . unshift ( ".env.local" ) if ENV [ "RAILS_ENV" ] == "test"
module YourApp
class Application < Rails :: Application
# ...
end
end
可用选项:
Dotenv::Rails.files
- 要加载的文件列表,按优先顺序排列。Dotenv::Rails.overwrite
- 使用.env*
文件的内容覆盖现有ENV
变量Dotenv::Rails.logger
- 用于 dotenv 日志记录的记录器。默认为Rails.logger
Dotenv::Rails.autorestore
- 启用或禁用自动恢复带换行符的多行值必须用双引号引起来。
PRIVATE_KEY= " -----BEGIN RSA PRIVATE KEY-----
...
HkVN9...
...
-----END DSA PRIVATE KEY----- "
在 3.0 之前,dotenv 会用换行符替换带引号的字符串中的n
,但该行为已被弃用。要使用旧行为,请在包含n
任何变量之前设置DOTENV_LINEBREAK_MODE=legacy
:
DOTENV_LINEBREAK_MODE=legacy
PRIVATE_KEY= " -----BEGIN RSA PRIVATE KEY-----nHkVN9...n-----END DSA PRIVATE KEY-----n "
您需要在变量之一中添加命令的输出吗?只需使用$(your_command)
添加它:
DATABASE_URL= " postgres:// $( whoami ) @localhost/my_database "
您需要将另一个变量的值添加到您的一个变量中吗?您可以使用${VAR}
引用变量,或者通常仅使用不带引号或双引号的值中的$VAR
来引用变量。
DATABASE_URL= " postgres:// ${USER} @localhost/my_database "
如果值包含$
并且它不打算作为变量,请将其用单引号引起来。
PASSWORD= ' pas$word '
注释可以添加到您的文件中,如下所示:
# This is a comment
SECRET_KEY=YOURSECRETKEYGOESHERE # comment
SECRET_HASH= " something-with-a-#-hash "
为了兼容性,您还可以在每行前面添加export
,以便您可以在 bash 中source
文件:
export S3_BUCKET=YOURS3BUCKET
export SECRET_KEY=YOURSECRETKEYGOESHERE
如果需要但未设置特定的配置值,则可以适当地引发错误。
需要配置密钥:
# config/initializers/dotenv.rb
Dotenv . require_keys ( "SERVICE_APP_ID" , "SERVICE_KEY" , "SERVICE_SECRET" )
如果未设置上述任何配置键,您的应用程序将在初始化期间引发错误。此方法是首选方法,因为它可以防止生产应用程序中由于配置不当而导致的运行时错误。
要解析 env 文件列表以进行编程检查而不修改 ENV:
Dotenv . parse ( ".env.local" , ".env" )
# => {'S3_BUCKET' => 'YOURS3BUCKET', 'SECRET_KEY' => 'YOURSECRETKEYGOESHERE', ...}
此方法返回 ENV var 名称/值对的哈希值。
您可以在 dotenv cli 上使用-t
或--template
标志来创建.env
文件的模板。
$ dotenv -t .env
将在您的工作目录中创建一个名为{FILENAME}.template
模板。因此,在上面的示例中,它将创建一个.env.template
文件。
该模板将包含.env
文件中的所有环境变量,但它们的值设置为变量名称。
# .env
S3_BUCKET=YOURS3BUCKET
SECRET_KEY=YOURSECRETKEYGOESHERE
会变成
# .env.template
S3_BUCKET=S3_BUCKET
SECRET_KEY=SECRET_KEY
dotenv 最初是为了在开发中将配置变量加载到ENV
中而创建的。通常有更好的方法来管理生产环境中的配置 - 例如由 Puppet 或 Chef 管理的/etc/environment
、 heroku config
等。
然而,有些人发现 dotenv 是在暂存和生产环境中配置 Rails 应用程序的便捷方法,您可以通过定义特定于环境的文件(例如.env.production
或.env.test
)来实现这一点。
如果您使用此 gem 处理多个 Rails 环境(开发、测试、生产等)的环境变量,请注意,所有环境通用的环境变量应存储在.env
中。然后,特定于环境的环境变量应存储在.env.
中。
凭证只能在需要访问凭证的计算机上才能访问。切勿将敏感信息提交到并非每台开发计算机和服务器都需要的存储库。
就个人而言,我更喜欢使用仅开发设置提交.env
文件。这使得其他开发人员可以轻松开始该项目,而不会影响其他环境的凭据。如果您遵循此建议,请确保您的开发环境的所有凭据都与其他部署不同,并且开发凭据无权访问任何机密数据。
ENV
变量?默认情况下,它不会覆盖现有的环境变量,因为 dotenv 假设部署环境比应用程序拥有更多有关配置的知识。要覆盖现有环境变量,您可以使用Dotenv.load files, overwrite: true
。
您还可以在 dotenv cli 上使用-o
或--overwrite
标志来覆盖现有ENV
变量。
$ dotenv -o -f " .env.local,.env "
如果您想更好地了解 dotenv 的工作原理,请查看 dotenv 的 Ruby Rogues 代码阅读。
git checkout -b my-new-feature
)git commit -am 'Added some feature'
)git push origin my-new-feature
)