我一直在开发一些 Node 应用程序,并且一直在寻找一种存储部署相关设置的良好模式。在 Django 世界(我来自的地方)中,常见的做法是拥有一个包含标准设置(时区等)的 settings.py
文件,然后是一个 local_settings.py< /code> 用于部署特定设置,即。与什么数据库通信,什么内存缓存套接字,管理员的电子邮件地址等等。
我一直在为 Node.js 寻找类似的模式。只要有一个配置文件就很好了,因此它不必与 app.js
中的其他所有内容混在一起,但我发现有一种方法可以在文件中包含特定于服务器的配置,这一点很重要这不在源代码管理中。同一个应用程序很可能部署在具有截然不同设置的不同服务器上,并且必须处理合并冲突以及所有这些都不是我的乐趣所在。
那么是否有某种框架/工具可以实现这一点,或者每个人都自己一起开发一些东西?
I have been working on a few Node apps, and I've been looking for a good pattern of storing deployment-related settings. In the Django world (where I come from), the common practise would be to have a settings.py
file containing the standard settings (timezone, etc), and then a local_settings.py
for deployment specific settings, ie. what database to talk to, what memcache socket, e-mail address for the admins and so on.
I have been looking for similar patterns for Node. Just a config file would be nice, so it does not have to be jammed in with everything else in app.js
, but I find it important to have a way to have server-specific configuration in a file that is not in source control. The same app could well be deployed across different servers with wildly different settings, and having to deal with merge conflicts and all that is not my idea of fun.
So is there some kind of framework/tool for this, or does everyone just hack something together themselves?
发布评论
评论(30)
我使用
package.json
作为我的包,使用config.js
作为我的配置,它看起来像:我从我的项目加载配置:
然后我可以访问我的来自
config.db_host
、config.db_port
等的内容...这使我可以使用硬编码参数,或者如果我不想存储,则可以使用存储在环境变量中的参数源代码管理中的密码。我还生成
package.json
并插入依赖项部分:当我将项目克隆到本地计算机时,我运行
npm install
来安装软件包。有关该内容的更多信息此处。该项目存储在 GitHub 中,并为我的生产服务器添加了遥控器。
I use a
package.json
for my packages and aconfig.js
for my configuration, which looks like:I load the config from my project:
and then I can access my things from
config.db_host
,config.db_port
, etc... This lets me either use hardcoded parameters, or parameters stored in environmental variables if I don't want to store passwords in source control.I also generate a
package.json
and insert a dependencies section:When I clone the project to my local machine, I run
npm install
to install the packages. More info on that here.The project is stored in GitHub, with remotes added for my production server.
从 Node v0.5.x 开始,您可以要求 JSON 文件(引用此答案)
config.json:
app.js:
You can require JSON files as of Node v0.5.x (referencing this answer)
config.json:
app.js:
很久以后,我发现了一个非常好的用于管理配置的 Node.js 模块:nconf。
一个简单的例子:
它还支持在 Redis 中存储设置,编写配置文件,并且具有相当可靠的 API,并且还得到以下之一的支持更多受人尊敬的 Node.js 商店 Nodejitsu,作为 Flatiron 的一部分 框架倡议,所以它应该是相当面向未来的。
查看 Github 上的 nconf。
Much later, I found a pretty good Node.js module for managing configuration: nconf.
A simple example:
It also supports storing settings in Redis, writing configuration files, and has a fairly solid API, and is also backed by one of the more well-respected Node.js shops, Nodejitsu, as part of the Flatiron framework initiative, so it should be fairly future-proof.
Check out nconf at Github.
我的解决方案相当简单:
在 ./config/index.js 中加载环境配置 在 ./config/config.global.js
中定义一些默认值
覆盖 ./config/config.test.js 中的默认值
在 ./models 中使用它/user.js:
在测试环境中运行您的应用程序:
My solution is fairly simple:
Load the environment config in ./config/index.js
Define some defaults in ./config/config.global.js
Override the defaults in ./config/config.test.js
Using it in ./models/user.js:
Running your app in test environment:
您还可以查看dotenv,它遵循12个原则-因素应用程序。
我曾经使用node-config,但出于这个原因创建了dotenv。它完全受到 ruby 的 dotenv 库的启发。
使用非常简单:
然后您只需创建一个 .env 文件并将设置放入其中,如下所示:
这就是 Nodejs 的 dotenv 。
You might also look to dotenv which follows the tenets of a twelve-factor app.
I used to use node-config, but created dotenv for that reason. It was completely inspired by ruby's dotenv library.
Usage is quite easy:
Then you just create a .env file and put your settings in there like so:
That's dotenv for nodejs.
你们使用 npm 来启动脚本(env 等)吗?
如果您使用
.env
文件,您可以将它们包含在package.json
中并使用 npm 来获取/启动它们。
示例:
然后运行 npm 脚本:
此处描述 https://gist.github.com/ericelliott/4152984
全部归功于埃里克·埃利奥特
Are you guys using npm to start your scripts (env etc) ?
If you use
.env
files you can include them in yourpackage.json
and use npm to source/start them.
Example:
then run the npm scripts:
Its described here https://gist.github.com/ericelliott/4152984
All credit to Eric Elliot
您还可以查看 node-config ,它根据 $HOST 和 $NODE_ENV 变量(有点像 RoR):文档。
这对于不同的部署设置(
开发
、测试
或生产
)非常有用。You might also look to node-config which loads configuration file depending on $HOST and $NODE_ENV variable (a little bit like RoR) : documentation.
This can be quite useful for different deployment settings (
development
,test
orproduction
).只需使用
exports
执行一个简单的settings.js
:然后,在您的脚本中执行
require
:现在您的所有设置都将通过 <代码>设置变量:
Just do a simple
settings.js
withexports
:Then, in your script, do a
require
:All your settings now will be availabe via
settings
variable:Convict 是另一个添加验证模式的选项。与 nconf 一样,它支持从环境变量、参数、文件和 json 对象的任意组合加载设置。
自述文件中的示例:
入门文章:
使用 node-convict 驯服配置
Convict is another option that adds a schema for validation. Like nconf, it supports loading settings from any combination of environment variables, arguments, files, and json objects.
Example from the README:
Getting started article:
Taming Configurations with node-convict
我要在这里表示敬意,因为这些答案都没有解决几乎任何系统所需的所有关键组件。注意事项:
以下是我的配置方式:
config.default.private.js
- 在版本控制中,这些是默认配置选项,只能由后端看到。config.default.public.js
- 在版本控制中,这些是后端和前端可以看到的默认配置选项config.dev.private.js< /code> - 如果您需要不同的开发私有默认值。
config.dev.public.js
- 如果您需要不同的开发公共默认值。config.private.js
- 不在版本控制中,这些是覆盖config.default.private.js
config.public.js
> - 不在版本控制中,这些是覆盖 config.default.public.js 的环境特定选项keys/
- 每个文件存储某种不同秘密的文件夹。这也不受版本控制(密钥永远不应该受版本控制)。我使用普通的 javascript 文件进行配置,因此我拥有 javascript 语言的全部功能(包括注释和执行诸如在特定于环境的文件中加载默认配置文件之类的操作的能力,以便可以覆盖它们)。如果你想使用环境变量,你可以将它们加载到这些配置文件中(尽管我建议不要使用环境变量,因为我不建议使用 json 文件的原因相同 - 你没有编程语言来构建的能力)你的配置)。
每个密钥位于单独的文件中的原因是供安装程序使用。这允许您拥有一个在计算机上创建密钥并将其存储在密钥文件夹中的安装程序。如果没有这个,当您加载无法访问密钥的配置文件时,安装程序可能会失败。通过这种方式,您可以遍历目录并加载该文件夹中的任何关键文件,而不必担心任何给定版本的代码中存在哪些文件以及不存在哪些文件。
由于您可能在私有配置中加载了密钥,因此您肯定不想在任何前端代码中加载您的私有配置。虽然将前端代码库与后端完全分离可能更理想,但很多时候 PITA 是一个足够大的障碍来阻止人们这样做,因此私有配置与公共配置。但是我做了两件事来防止在前端加载私有配置:
最后一件事:您的配置应该通过一个与任何其他前端代码完全独立的文件加载到浏览器中。如果您捆绑前端代码,则公共配置应构建为完全独立的捆绑包。否则,您的配置不再是真正的配置 - 它只是代码的一部分。配置需要能够在不同的机器上有所不同。
I'm going to throw my hat into the ring here because none of these answers address all the critical components that pretty much any system needs. Considerations:
Here's how I do my configuration:
config.default.private.js
- In version control, these are default configuration options that can only be seen by your backend.config.default.public.js
- In version control, these are default configuration options that can be seen by backend and frontendconfig.dev.private.js
- If you need different private defaults for dev.config.dev.public.js
- If you need different public defaults for dev.config.private.js
- Not in version control, these are environment specific options that overrideconfig.default.private.js
config.public.js
- Not in version control, these are environment specific options that overrideconfig.default.public.js
keys/
- A folder where each file stores a different secret of some kind. This is also not under version control (keys should never be under version control).I use plain-old javascript files for configuration so I have the full power of the javascript langauge (including comments and the ability to do things like load the default config file in the environment-specific file so they can then be overridden). If you want to use environment variables, you can load them inside those config files (tho I recommend against using env vars for the same reason I don't recommend using json files - you don't have the power of a programming language to construct your config).
The reason each key is in a separate file is for installer use. This allows you to have an installer that creates keys on-machine and stores them in the keys folder. Without this, your installer might fail when you load your configuration file that can't access your keys. This way you can traverse the directory and load any key files that are in that folder without having to worry about what exists and what doesn't in any given version of your code.
Since you probably have keys loaded in your private configuration, you definitely don't want to load your private config in any frontend code. While its probably strictly more ideal to completely separate your frontend codebase from your backend, a lot of times that PITA is a big enough barrier to prevent people from doing it, thus private vs public config. But there's two things I do to prevent private config being loaded in the frontend:
One last thing: your configuration should be loaded into the browser via a completely separate file than any of your other frontend code. If you bundle your frontend code, the public configuration should be built as a completely separate bundle. Otherwise, your config isn't really config anymore - its just part of your code. Config needs to be able to be different on different machines.
您可以使用 Konfig 来获取特定于环境的配置文件。它自动加载 json 或 yaml 配置文件,具有默认值和动态配置功能。
Konfig 存储库中的示例:
在开发中:
在生产中,假设我们使用
$ NODE_ENV=production PORT=4567 node app.js
启动应用程序更多详细信息:https://github.com/vngrs/konfig
You can use Konfig for environment specific config files. It loads json or yaml config files automatically, it has default value and dynamic configuration features.
An example from Konfig repo:
In development:
In production, assume we start application with
$ NODE_ENV=production PORT=4567 node app.js
More details : https://github.com/vngrs/konfig
我将创建一个文件夹作为配置文件,命名为 config.js ,稍后我将在需要的地方使用此文件,如下所示
config.js 示例
然后,如果我想在某处使用此配置文件,
我将首先如下导入
var config = require('./config');
我可以访问以下值
I will create a folder as config a file naming as
config.js
and later I will use this file wherever required as belowExample of config.js
Then if i want to use this config file somewhere
I will first import as below
var config = require('./config');
and I can access the values as below
只需使用
npm
模块config
(超过300000次下载)https://www.npmjs.com/package/config
Node-config 为您的应用程序部署组织分层配置。
它允许您定义一组默认参数,并将它们扩展到不同的部署环境(开发、质量保证、登台、生产等)。
Just use
npm
moduleconfig
(more than 300000 downloads)https://www.npmjs.com/package/config
Node-config organizes hierarchical configurations for your app deployments.
It lets you define a set of default parameters, and extend them for different deployment environments (development, qa, staging, production, etc.).
有点晚了(仅仅 10 年),但我使用了如下结构的 config.js:
我加载配置:
以这种方式:
config.js
可以上传到代码存储库中,因为敏感变量继续由process.env
处理。default:{
和custom_env:{
中都包含相同的元素,则仅保留第二个元素。A bit late (just 10 year) but I use a
config.js
structured like this:and I load the config with:
In this way:
env
variable is included in theconfig.js
file so I can avoid this ugliness:require('./config')[process.env.NODE_ENV || 'development']
.config.js
can be uploaded in the code 's repo because sensitive variables continue to be handled withprocess.env
.default:{
andcustom_env:{
only the second is kept.我知道这是一篇非常旧的帖子。但我想分享我的用于配置环境变量的模块,我认为这是非常灵活的解决方案。
这是模块 json-configurator
然后你可以使用
process.env.NODE_ENV
获取您的环境的所有变量。I know this is a really old post. But I want to share my module for configuring environment variables, I think it is very flexible solution.
Here is the module json-configurator
Then you can use
process.env.NODE_ENV
to get all the variables for your environment.最好将'开发'和'生产'配置分开。
我使用以下方式:
这是我的 config/index.js 文件:
对于需要配置,请使用以下内容:
您可以使用您的配置对象:
It's better to separate 'development' and 'production' configs.
I use following way:
Here is my config/index.js file:
For require the config use following:
Than you can use your config object:
我在游戏中有点晚了,但我在这里或其他地方找不到我需要的东西,所以我自己写了一些东西。
我对配置机制的要求如下:
settings-overrides.js
- 看起来相同,但允许覆盖settings.js
中的配置。这里的想法是在不更改代码的情况下轻松修改配置。我发现它对于 saas 很有用。即使我不太关心支持环境 - 也会解释如何将其轻松添加到我的解决方案
中 解释
undefined
表示此属性是必需的null
表示它是可选的meConf
- 目前代码的目标是app
下的文件。meConf
是针对conf/dev
的覆盖文件 - 它被我的 vcs 忽略。publicConfiguration
- 从前端和后端可见。privateConfiguration
- 仅在后端可见。sendPublicConfiguration
- 将公开公共配置并将其分配给全局变量的路由。例如,下面的代码将在前端将公共配置公开为全局变量 myConf。默认情况下它将使用全局变量名称conf
。app.get("/backend/conf", require("conf").sendPublicConfiguration);
覆盖 privateConfiguration 的逻辑
添加环境支持
尽管我不认为“环境支持”有用,但也许有人会。
要添加环境支持,您需要将 meConf require 语句更改为类似这样的内容(伪代码)
if (environment == "Production") {
meConf = require("../conf/dev/meConf"). Production;
}
if (环境==“开发”){
meConf = require("../conf/dev/meConf").development;
同样,
您可以为每个环境创建一个文件
并导入正确的文件。
其余逻辑保持不变。
I am a bit late in the game, but I couldn't find what I needed here- or anywhere else - so I wrote something myself.
My requirements for a configuration mechanism are the following:
settings-overrides.js
- which looks the same but allows overrides of configuration atsettings.js
. The idea here is to modify configuration easily without changing the code. I find it useful for saas.Even though I care less about supporting environments - the will explain how to add it easily to my solution
Explanation
undefined
means this property is requirednull
means it is optionalmeConf
- currently the code is target to a file underapp
.meConf
is the overrides files which is targeted toconf/dev
- which is ignored by my vcs.publicConfiguration
- will be visible from front-end and back-end.privateConfiguration
- will be visible from back-end only.sendPublicConfiguration
- a route that will expose the public configuration and assign it to a global variable. For example the code below will expose the public configuration as global variable myConf in the front-end. By default it will use the global variable nameconf
.app.get("/backend/conf", require("conf").sendPublicConfiguration);
Logic of overrides
Adding environment support
Even though I don't find an "environment support" useful, maybe someone will.
To add environment support you need to change the meConf require statement to something like this (pseudocode)
if ( environment == "production" ) {
meConf = require("../conf/dev/meConf").production;
}
if ( environment == "development" ) {
meConf = require("../conf/dev/meConf").development;
}
Similarly you can have a file per environment
and import the right one.
The rest of the logic stays the same.
我刚刚使用的替代示例是因为我想要比典型的 .json 文件更灵活,但不希望将其抽象到需要依赖项的库中,就像这样。基本上,导出一个立即调用的函数,该函数返回一个具有我想要设置的值的对象。提供很大的灵活性。
这里有一个更好的解释和完整的例子。 在 Node.js 中使用配置文件
an alt example I just used because I wanted more flexibility than a typical .json file but didn't want it abstracted away into a library which would require a dependency is something like this. Basically, exporting a function invoked immediately which returned an object with values I wanted set. Gives a lot of flexibility.
There is a much better explanation with full example here. Using Config Files in Node.js
这是一种受这篇文章启发的简洁方法。除了无处不在的 lodash 包之外,它不需要任何其他包。此外,它还允许您通过特定于环境的覆盖来管理嵌套默认值。
首先,在包根路径中创建一个 config 文件夹,如下所示,
这里是 index.js 文件
现在假设我们有一个像这样的 defaults.json
和像这样的development.json,
如果您执行
config = require(' ./config')
这是您将得到的内容。请注意,您将获得除特定于环境的文件中定义的值之外的所有默认值。因此您可以管理配置层次结构。使用defaultsDeep可以确保您甚至可以拥有嵌套的默认值。
Here is a neat approach inspired by this article. It does not require any additional packages except the ubiquitous lodash package. Moreover, it lets you manage nested defaults with environment-specific overwrites.
First, create a config folder in the package root path that looks like this
here is the index.js file
Now let's assume we have a defaults.json like so
and development.json like so
if you do
config = require('./config')
here is what you will getNotice that you get all the default values except for those defined in environment-specific files. So you can manage a config hierarchy. Using
defaultsDeep
makes sure that you can even have nested defaults.除了 nconf 模块 /5869216/how-to-store-node-js-deployment-settings-configuration-files/8563528#8563528">这个答案,以及node-config 1411373">这个答案,还有node-iniparser和 IniReader,它们似乎是更简单的 .ini 配置文件解析器。
In addition to the nconf module mentioned in this answer, and node-config mentioned in this answer, there are also node-iniparser and IniReader, which appear to be simpler .ini configuration file parsers.
我最近刚刚发布了一个小模块来加载任何类型的配置文件。
这非常简单,您可以在 https://github.com/flesler/config-node< /a>
I just recently released a small module to load any type of configuration files.
It's pretty straight-forward, you can check it at https://github.com/flesler/config-node
您可以使用 pconf: https://www.npmjs.com/package/pconf
示例:
You can use pconf: https://www.npmjs.com/package/pconf
Example:
我使用 Dotenv-Flow 进行配置管理。
1. npm i dotenv-flow。
2. 创建类似
.env | 的文件.env.dev | .env.prod
。出于测试目的,请复制此内容
.env
.env.dev
.env.prod
现在使用这些环境变量创建一个测试文件。
test.js
< strong>现在使用这些命令来运行您的脚本。
如果您在特定文件夹中创建这些环境变量文件,就像在我的例子中一样,我已在 envs 文件夹中创建了这些文件,然后使用以下命令。 >
I used Dotenv-Flow for configuration management.
1. npm i dotenv-flow.
2. Create files like
.env | .env.dev | .env.prod
.For testing purposes copy this content
.env
.env.dev
.env.prod
Now create a test file use these environment variables.
test.js
Now use these commands to run your script.
If you create these environment variables files in a specific folder like in my case I have created these files in envs folder then use the below command.
对于那些访问这个旧线程的人来说,这里有一个我认为很好的包。
https://www.npmjs.org/package/config
For those who are visiting this old thread here is a package I find to be good.
https://www.npmjs.org/package/config
我在这里尝试了一些建议的解决方案,但对它们不满意,所以我创建了自己的模块。它称为 mikro-config,主要区别在于它遵循约定优于配置,因此您只需需要该模块即可开始使用它。
您可以将配置存储在
/config
文件夹中的纯 js 或 json 文件中。首先,它加载default.js
文件,然后加载/config
目录中的所有其他文件,然后根据$NODE_ENV
变量加载环境特定配置。它还允许使用
local.js
或特定于环境的/config/env/$NODE_ENV.local.js
覆盖此配置以进行本地开发。您可以在这里查看它:
https://www.npmjs.com/package/mikro -config
https://github.com/B4nan/mikro-config
I tryied some of suggested solutions here, but was not sattisfied with them, so I created my own module. It is called
mikro-config
and the main difference is that it honors convention over configuration, so you can just require the module and start using it.You store your configuration in either plain js, or json files from
/config
folder. First it loadsdefault.js
file, then all other files from/config
directory, then it loads environment specific configuration based on$NODE_ENV
variable.It also allows to override this configuration for local development with
local.js
or environment specific/config/env/$NODE_ENV.local.js
.You can take at look at it here:
https://www.npmjs.com/package/mikro-config
https://github.com/B4nan/mikro-config
长期以来,我一直使用此处解决方案中提到的方法。然而,人们对明文秘密的安全性存在担忧。您可以在
config
之上使用另一个包,以便处理安全位。看看这个: https://www .attosol.com/secure-application-secrets-using-masterkey-in-azure-key-vault/
For long, I used to use the approach mentioned in the solution here. There is a concern however, about security of the secrets in clear text. You can use another package on top of
config
so that the security bits are taken care of.Check this out: https://www.attosol.com/secure-application-secrets-using-masterkey-in-azure-key-vault/
我们如何使用 TypeScript 做到这一点。
How we do it with TypeScript.
如今,在使用数据库时,最简单的方法是根本不处理配置文件,因为仅使用单个环境变量(例如,将其称为
DB_CONNECTION
)即可更轻松地设置部署环境,并且根据需要向其传递任何其他配置数据。配置数据示例:
创建一个连接字符串,其中包含数据库驱动程序不关心的额外参数:
然后我们可以生成结果字符串以将其存储在环境中:
因此您可以将其存储在您的环境中,比方说,
DB_CONNECTION
,在客户端进程中,您可以通过process.env.DB_CONNECTION
读取它:这样您将同时拥有连接和所有额外的信息。所需的配置全部在一个单一的环境变量,无需搞乱配置文件。
These days, when working with databases it is the easiest not to deal with configuration files at all, because deployment environments are easier to set up with just a single environment variable, call it
DB_CONNECTION
, for example, and pass it any additional configuration data as required.configuration data example:
Create a connection string, with extra parameters that the database driver doesn't care about:
Then we can generate the resulting string for storing it in the environment:
So you store this in your environment, let's say,
DB_CONNECTION
, and within the client process you can just read it viaprocess.env.DB_CONNECTION
:This way you will have both the connection, and all the extra configuration needed, all within a single environment variable, no need messing with configuration files.
尝试使用properties-gen
https://www.npmjs.com/package/properties-gen
非常类似于
node-config
加载配置基础文件并根据您设置的环境使用 ext 文件对其进行扩展,但这是一个按需运行且完全可配置的 cli。要创建 cli 配置,然后将其安装在项目中
定义配置文件(基本文件和扩展文件)并在构建过程之前或在项目中启动开发服务器之前运行
generate
命令。一件很酷的事情是,您可以定义多个配置组,以防您需要生成多个输出,例如客户端和服务器特定文件。
Try with
properties-gen
https://www.npmjs.com/package/properties-gen
Pretty similar to
node-config
which loads a configuration base file and extends it with an ext file depending on the environment you set, but this is a cli that runs on demand and is fully configurable.To create the cli configuration, then install it in your project
Define your configuration files (base and extensions) and run the
generate
command before build process or before starting dev server in your project.One cool thing is you can define multiple configuration groups, in case you need to generate multiple outputs for example a client and server specific files.