如何存储Node.js部署设置/配置文件?

时间:2011-05-03 12:09:08

标签: node.js configuration-files

我一直在研究一些Node应用程序,我一直在寻找一种存储部署相关设置的良好模式。在Django世界(我来自哪里),通常的做法是使用settings.py文件包含标准设置(时区等),然后使用local_settings.py进行部署特定设置,即。要与哪个数据库通信,什么是memcache套接字,管理员的电子邮件地址等等。

我一直在寻找类似Node的模式。只是一个配置文件会很好,所以它不必与app.js中的其他所有内容一起使用,但我发现在一个不在源文件中的文件中有一种特定于服务器的配置很重要控制。相同的应用程序可以在不同的服务器上部署,具有完全不同的设置,并且必须处理合并冲突,所有这些都不是我的乐趣。

那么是否有某种框架/工具,或者每个人都自己一起破解某些东西?

28 个答案:

答案 0 :(得分:735)

我的配置使用package.json,配置使用config.js,如下所示:

var config = {};

config.twitter = {};
config.redis = {};
config.web = {};

config.default_stuff =  ['red','green','blue','apple','yellow','orange','politics'];
config.twitter.user_name = process.env.TWITTER_USER || 'username';
config.twitter.password=  process.env.TWITTER_PASSWORD || 'password';
config.redis.uri = process.env.DUOSTACK_DB_REDIS;
config.redis.host = 'hostname';
config.redis.port = 6379;
config.web.port = process.env.WEB_PORT || 9980;

module.exports = config;

我从项目加载配置:

var config = require('./config');

然后我可以从config.db_hostconfig.db_port等访问我的东西......如果我不想存储密码,我可以使用硬编码参数或存储在环境变量中的参数在源代码管理中。

我还生成package.json并插入依赖项部分:

"dependencies": {
  "cradle": "0.5.5",
  "jade": "0.10.4",
  "redis": "0.5.11",
  "socket.io": "0.6.16",
  "twitter-node": "0.0.2",
  "express": "2.2.0"
}

当我将项目克隆到本地计算机时,我运行npm install来安装软件包。关于here的更多信息。

该项目存储在GitHub中,并为我的生产服务器添加了遥控器。

答案 1 :(得分:230)

从Node v0.5.x(referencing this answer

开始,您可以要求JSON文件

config.json:

{
    "username" : "root",
    "password" : "foot"
}

app.js:

var config = require('./config.json');
log_in(config.username, config.password);

答案 2 :(得分:189)

很久以后,我找到了一个非常好的Node.js模块来管理配置:nconf

一个简单的例子:

var nconf = require('nconf');

// First consider commandline arguments and environment variables, respectively.
nconf.argv().env();

// Then load configuration from a designated file.
nconf.file({ file: 'config.json' });

// Provide default values for settings not provided above.
nconf.defaults({
    'http': {
        'port': 1337
    }
});

// Once this is in place, you can just use nconf.get to get your settings.
// So this would configure `myApp` to listen on port 1337 if the port
// has not been overridden by any of the three configuration inputs
// mentioned above.
myApp.listen(nconf.get('http:port'));

它还支持在Redis中存储设置,编写配置文件,并且具有相当可靠的API,并且还受到一个备受推崇的Node.js商店Nodejitsu的支持, Flatiron框架倡议的一部分,因此它应该是相当面向未来的。

查看nconf at Github

答案 3 :(得分:85)

我的解决方案非常简单:

在./config/index.js

中加载环境配置
var env = process.env.NODE_ENV || 'development'
  , cfg = require('./config.'+env);

module.exports = cfg;

在./config/config.global.js

中定义一些默认值
var config = module.exports = {};

config.env = 'development';
config.hostname = 'dev.example.com';

//mongo database
config.mongo = {};
config.mongo.uri = process.env.MONGO_URI || 'localhost';
config.mongo.db = 'example_dev';

覆盖./config/config.test.js

中的默认值
var config = require('./config.global');

config.env = 'test';
config.hostname = 'test.example';
config.mongo.db = 'example_test';

module.exports = config;

在./models/user.js中使用它:

var mongoose = require('mongoose')
, cfg = require('../config')
, db = mongoose.createConnection(cfg.mongo.uri, cfg.mongo.db);

在测试环境中运行您的应用:

NODE_ENV=test node ./app.js

这里有更详细的解释:http://www.chovy.com/node-js/managing-config-variables-inside-a-node-js-application/

答案 4 :(得分:31)

您也可以查看符合dotenv原则的twelve-factor app

我曾经使用node-config,但出于这个原因创建了dotenv。它完全受到ruby的dotenv库的启发。

使用非常简单:

var dotenv = require('dotenv');
dotenv.load();

然后你只需创建一个.env文件并将设置放在那里:

S3_BUCKET=YOURS3BUCKET
SECRET_KEY=YOURSECRETKEYGOESHERE
OTHER_SECRET_STUFF=my_cats_middle_name

对于nodejs来说是dotenv

答案 5 :(得分:29)

你们是否正在使用npm来启动脚本(env等)?

如果您使用.env个文件,则可以将其包含在package.json中 并使用npm来源/启动它们。

示例:

{
  "name": "server",
  "version": "0.0.1",
  "private": true,
  "scripts": {
    "start": "node test.js",
    "start-dev": "source dev.env; node test.js",
    "start-prod": "source prod.env; node test.js"
  },
  "dependencies": {
    "mysql": "*"
  }
}

然后运行npm脚本:

$ npm start-dev

此处描述https://gist.github.com/ericelliott/4152984 全部归功于Eric Elliot

答案 6 :(得分:22)

您可能还会根据 $ HOST $ NODE_ENV 变量(有点像RoR)来查看加载配置文件的node-config:{{3 }}

这对于不同的部署设置(developmenttestproduction)非常有用。

答案 7 :(得分:20)

只需使用settings.js执行简单的exports

exports.my_password = 'value'

然后,在您的脚本中,执行require

var settings = require('./settings.js');

现在,您可以通过settings变量

获取所有设置
settings.my_password // 'value'

答案 8 :(得分:12)

我要在这里把帽子扔进戒指,因为这些答案都没有解决几乎任何系统需要的所有关键组件。考虑:

  • 公共配置(前端可以看到)vs私人配置(家伙mograbi得到了这个权利)。并确保将它们分开。
  • 密钥之类的秘密
  • 默认值与特定于环境的覆盖
  • 前端捆绑

以下是我的配置方式:

  • config.default.private.js - 在版本控制中,这些是默认配置选项,只能由后端查看。
  • config.default.public.js - 在版本控制中,这些是后端前端可以看到的默认配置选项
  • config.dev.private.js - 如果您需要dev的不同私人默认值。
  • config.dev.public.js - 如果您需要dev的不同公共默认值。
  • config.private.js - 不在版本控制中,这些是覆盖config.default.private.js
  • 的特定于环境的选项
  • config.public.js - 不在版本控制中,这些是覆盖config.default.public.js
  • 的特定于环境的选项
  • keys/ - 每个文件存储某种不同秘密的文件夹。这也不受版本控制(键不应该受版本控制)。

我使用普通的javascript文件进行配置,因此我充分掌握了javascript语言(包括注释和执行操作的能力,例如在环境特定的文件中加载默认配置文件,以便可以覆盖它们) 。如果你想使用环境变量,你可以在这些配置文件中加载它们(因为我不推荐使用json文件,因此我建议不要使用env vars - 你不具备强大的功能编程语言来构建你的配置。)

每个密钥位于单独文件中的原因是供安装程序使用。这允许您拥有一个在机器上创建密钥的安装程序,并将它们存储在密钥文件夹中。如果没有这个,当您加载无法访问密钥的配置文件时,安装程​​序可能会失败。这样,您可以遍历目录并加载该文件夹中的所有密钥文件,而无需担心任何给定版本的代码中存在的内容和内容。

由于您的私有配置中可能已加载密钥,因此您肯定不想在任何前端代码中加载私有配置。虽然将前端代码库与后端完全分离可能非常理想,但很多时候PITA是阻止人们进行操作的一大屏障,因此私有vs公共配置。但是我要做的两件事是阻止在前端加载私有配置:

  1. 我有一个单元测试,确保我的前端捆绑包不包含私有配置中的一个密钥。
  2. 我的前端代码位于与后端代码不同的文件夹中,我有两个不同的文件名为" config.js" - 每一端一个。对于后端,config.js加载私有配置,对于前端,它加载公共配置。然后你总是需要(' config')并且不用担心它来自哪里。
  3. 最后一件事:您的配置应通过完全单独的文件加载到浏览器中,而不是任何其他前端代码。如果捆绑前端代码,则应将公共配置构建为完全独立的捆绑包。否则,您的配置不再是真正的配置 - 它只是代码的一部分。配置需要能够在不同的机器上不同。

答案 9 :(得分:11)

Convict是另一个添加架构以进行验证的选项。与nconf一样,它支持从环境变量,参数,文件和json对象的任意组合加载设置。

自述文件中的示例:

var convict = require('convict');
var conf = convict({
  env: {
    doc: "The applicaton environment.",
    format: ["production", "development", "test"],
    default: "development",
    env: "NODE_ENV"
  },
  ip: {
    doc: "The IP address to bind.",
    format: "ipaddress",
    default: "127.0.0.1",
    env: "IP_ADDRESS",
  },
  port: {
    doc: "The port to bind.",
    format: "port",
    default: 0,
    env: "PORT"
  }
});

入门文章: Taming Configurations with node-convict

答案 10 :(得分:11)

您可以将Konfig用于特定于环境的配置文件。它自动加载json或yaml配置文件,它具有默认值和动态配置功能。<​​/ p>

Konfig repo的一个例子:

File: config/app.json
----------------------------
{
    "default": {
        "port": 3000,
        "cache_assets": true,
        "secret_key": "7EHDWHD9W9UW9FBFB949394BWYFG8WE78F"
    },

    "development": {
        "cache_assets": false
    },

    "test": {
        "port": 3001
    },

    "staging": {
        "port": #{process.env.PORT},
        "secret_key": "3F8RRJR30UHERGUH8UERHGIUERHG3987GH8"
    },

    "production": {
        "port": #{process.env.PORT},
        "secret_key": "3F8RRJR30UHERGUH8UERHGIUERHG3987GH8"
    }
}

在开发中:

> config.app.port
3000

在制作中,假设我们使用$ NODE_ENV=production PORT=4567 node app.js

开始申请
> config.app.port
4567

更多详情:https://github.com/vngrs/konfig

答案 11 :(得分:7)

我将创建一个文件夹作为配置文件命名为config.js,稍后我会在需要的地方使用此文件,如下所示

config.js的示例

module.exports = {
    proxyURL: 'http://url:port',
    TWITTER: {
        consumerkey: 'yourconsumerkey',
        consumerSecrete: 'yourconsumersecrete'
    },
    GOOGLE: {
        consumerkey: 'yourconsumerkey',
        consumerSecrete: 'yourconsumersecrete'
    },
    FACEBOOK: {
        consumerkey: 'yourconsumerkey',
        consumerSecrete: 'yourconsumersecrete'
    }
}

然后,如果我想在某处使用此配置文件

我将首先导入如下

var config = require('./config');

我可以访问以下值

const oauth = OAuth({
    consumer: {
        key: config.TWITTER.consumerkey,
        secret: config.TWITTER.consumerSecrete
    },
    signature_method: 'HMAC-SHA1',
    hash_function(base_string, key) {
        return crypto.createHmac('sha1', key).update(base_string).digest('base64');
    }
});

答案 12 :(得分:3)

我刚刚使用的alt示例,因为我想要比典型的.json文件更灵活,但是不希望它被抽象到一个需要依赖的库中。基本上,导出一个立即调用的函数,该函数返回一个具有我想要的值的对象。提供了很大的灵活性。

     module.exports = function(){
       switch(node_env){
         case 'dev':
           return
           { var1 = 'development'};
         }
    }();

这里有完整的例子,有一个更好的解释。 Using Config Files in Node.js

答案 13 :(得分:3)

只需使用npm模块config(超过300000次下载)

https://www.npmjs.com/package/config

Node-config为您的应用程序部署组织分层配置。

它允许您定义一组默认参数,并将其扩展为不同的部署环境(开发,质量保证,登台,生产等)。

$ npm install config
$ mkdir config
$ vi config/default.json


{
      // Customer module configs
      "Customer": {
        "dbConfig": {
          "host": "localhost",
          "port": 5984,
          "dbName": "customers"
        },
        "credit": {
          "initialLimit": 100,
          // Set low for development
          "initialDays": 1
        }
      }
}



$ vi config/production.json

{
  "Customer": {
    "dbConfig": {
      "host": "prod-db-server"
    },
    "credit": {
      "initialDays": 30
    }
  }
}



$ vi index.js

var config = require('config');
//...
var dbConfig = config.get('Customer.dbConfig');
db.connect(dbConfig, ...);

if (config.has('optionalFeature.detail')) {
  var detail = config.get('optionalFeature.detail');
  //...
}


$ export NODE_ENV=production
$ node index.js

答案 14 :(得分:3)

我知道这是一个非常古老的帖子。但我想分享我的模块来配置环境变量,我认为这是非常灵活的解决方案。 这是模块json-configurator

var configJson = {
  'baseUrl': 'http://test.com',
  '$prod_baseUrl': 'https://prod.com',
  'endpoints': {
    'users': '<%= baseUrl %>/users',
    'accounts': '<%= baseUrl %>/accounts'
    },
  foo: 'bar',
  foobar: 'foobar',
  $prod_foo: 'foo in prod',
  $test_foo: 'foo in test',
  deep:{
    veryDeep: {
      publicKey: 'abc',
      secret: 'secret',
      $prod_secret: 'super secret'
    }
  }
};

var config = require('json-configurator')(configJson, 'prod');

console.log(config.deep.veryDeep.secret) 
// super secret 

console.log(config.endpoints.users)
// https://prod.com/users 

然后,您可以使用process.env.NODE_ENV获取适合您环境的所有变量。

答案 15 :(得分:3)

我在游戏中有点晚了,但我找不到我需要的东西 - 或其他任何地方 - 所以我自己写了一些东西。

我对配置机制的要求如下:

  1. 支持前端。如果前端无法使用配置,有什么意义呢?
  2. 支持settings-overrides.js - 看起来相同但允许在settings.js覆盖配置。这里的想法是在不更改代码的情况下轻松修改配置。我觉得它对saas很有用。
  3. 即使我不太关心支持环境 - 这将解释如何轻松地将其添加到我的解决方案

    var publicConfiguration = {
        "title" : "Hello World"
        "demoAuthToken" : undefined, 
        "demoUserId" : undefined, 
        "errorEmail" : null // if null we will not send emails on errors. 
    
    };
    
    var privateConfiguration = {
        "port":9040,
        "adminAuthToken":undefined,
        "adminUserId":undefined
    }
    
    var meConf = null;
    try{
        meConf = require("../conf/dev/meConf");
    }catch( e ) { console.log("meConf does not exist. ignoring.. ")}
    
    
    
    
    var publicConfigurationInitialized = false;
    var privateConfigurationInitialized = false;
    
    function getPublicConfiguration(){
        if (!publicConfigurationInitialized) {
            publicConfigurationInitialized = true;
            if (meConf != null) {
                for (var i in publicConfiguration) {
                    if (meConf.hasOwnProperty(i)) {
                        publicConfiguration[i] = meConf[i];
                    }
                }
            }
        }
        return publicConfiguration;
    }
    
    
    function getPrivateConfiguration(){
        if ( !privateConfigurationInitialized ) {
            privateConfigurationInitialized = true;
    
            var pubConf = getPublicConfiguration();
    
            if ( pubConf != null ){
                for ( var j in pubConf ){
                    privateConfiguration[j] = pubConf[j];
                }
            }
            if ( meConf != null ){
                  for ( var i in meConf ){
                      privateConfiguration[i] = meConf[i];
                  }
            }
        }
        return privateConfiguration;
    
    }
    
    
    exports.sendPublicConfiguration = function( req, res ){
        var name = req.param("name") || "conf";
    
        res.send( "window." + name + " = " + JSON.stringify(getPublicConfiguration()) + ";");
    };
    
    
    var prConf = getPrivateConfiguration();
    if ( prConf != null ){
        for ( var i in prConf ){
            if ( prConf[i] === undefined ){
    
                throw new Error("undefined configuration [" + i + "]");
            }
            exports[i] = prConf[i];
        }
    }
    
    
    return exports;
    

    说明

    • undefined表示此属性是必需的
    • null表示它是可选的
    • meConf - 目前代码是app下文件的目标。 meConf是覆盖conf/dev的覆盖文件 - 我的vcs会忽略这些文件。
    • publicConfiguration - 将从前端和后端显示。
    • privateConfiguration - 仅在后端可见。
    • sendPublicConfiguration - 将公开公共配置并将其分配给全局变量的路由。例如,下面的代码将公共配置公开为前端的全局变量myConf。默认情况下,它将使用全局变量名称conf

      app.get(“/ backend / conf”,require(“conf”)。sendPublicConfiguration);

    覆盖逻辑

    • privateConfiguration与publicConfiguration合并,然后是meConf。
    • publicConfiguration检查每个键是否有覆盖,并使用该覆盖。这样我们就不会露出任何私密的东西了。

    添加环境支持

    即使我没有找到有用的“环境支持”,也许有人会。

    要添加环境支持,您需要将meConf require语句更改为此类(伪代码)

    if(environment ==“production”){         meConf = require(“../ conf / dev / meConf”)。生产;    }

    if(environment ==“development”){         meConf = require(“../ conf / dev / meConf”)。development;    }

    同样,您可以为每个环境提供一个文件

     meConf.development.js
     meConf.production.js
    

    并导入正确的。 其余的逻辑保持不变。

答案 16 :(得分:2)

最好将“开发” “生产” 配置分开。

我使用以下方式: 这是我的 config / index.js 文件:

const config = {
    dev : {
        ip_address : '0.0.0.0',
        port : 8080,
        mongo :{
            url : "mongodb://localhost:27017/story_box_dev",
            options : ""
        }
    },
    prod : {
        ip_address : '0.0.0.0',
        port : 3000,
        mongo :{
            url : "mongodb://localhost:27017/story_box_prod",
            options : ""
        }
    }
} 

对于要求配置使用以下内容:

const config = require('../config')[process.env.NODE_ENV];

比起您可以使用的配置对象:

const ip_address = config.ip_address;
const port = config.port;

答案 17 :(得分:2)

这是一种受this article启发的简洁方法。除了无处不在的lodash package外,它不需要任何其他软件包。此外,它还允许您使用特定于环境的覆盖来管理嵌套的默认值。

首先,在程序包根路径中创建一个如下所示的配置文件夹

package
  |_config
      |_ index.js
      |_ defaults.json
      |_ development.json
      |_ test.json
      |_ production.json

这是index.js文件

const _ = require("lodash");
const defaults = require("./defaults.json");
const envConf = require("./" + (process.env.NODE_ENV || "development") + ".json" );
module.exports = _.defaultsDeep(envConf, defaults);

现在让我们假设我们有一个defaults.json

{
  "confKey1": "value1",
  "confKey2": {
    "confKey3": "value3",
    "confKey4": "value4"
  }
}

和development.json一样

{
  "confKey2": {
    "confKey3": "value10",
  }
}

如果您进行config = require('./config'),这将为您提供

{
  "confKey1": "value1",
  "confKey2": {
    "confKey3": "value10",
    "confKey4": "value4"
  }
}

请注意,除特定于环境的文件中定义的默认值外,您将获得所有默认值。因此,您可以管理配置层次结构。使用defaultsDeep可确保您甚至可以拥有嵌套的默认值。

答案 18 :(得分:1)

您可以使用pconf:https://www.npmjs.com/package/pconf

示例:

var Config = require("pconf");
var testConfig = new Config("testConfig");
testConfig.onload = function(){

  testConfig.setValue("test", 1);
  testConfig.getValue("test");
  //testConfig.saveConfig(); Not needed

}

答案 19 :(得分:1)

我刚刚发布了一个小模块来加载任何类型的配置文件。 这很简单,您可以在https://github.com/flesler/config-node

查看

答案 20 :(得分:1)

nconf module中提到的this answernode-config中提及的this answer外,还有node-iniparserIniReader,其中似乎更简单.ini配置文件解析器。

答案 21 :(得分:1)

npm i config

In config/default.json
{
    "app": {
        "port": 3000
    },
    "db": {
        "port": 27017,
        "name": "dev_db_name"
    }
}

In config/production.json
{
    "app": {
        "port": 4000
    },
    "db": {
        "port": 27000,
        "name": "prod_db_name"
    }
}

In index.js

const config = require('config');

let appPort = config.get('app.port');
console.log(`Application port: ${appPort}`);

let dbPort = config.get('db.port');
console.log(`Database port: ${dbPort}`);

let dbName = config.get('db.name');
console.log(`Database name: ${dbName}`);

console.log('NODE_ENV: ' + config.util.getEnv('NODE_ENV'));

$ node index.js
Application port: 3000
Database port: 27017
Database name: dev_db_name
NODE_ENV: development

For production
$ set NODE_ENV=production
$ node index.js
Application port: 4000
Database port: 27000
Database name: prod_db_name
NODE_ENV: production

答案 22 :(得分:0)

对于那些正在访问这个旧帖子的人来说,这是一个我认为很好的包。

https://www.npmjs.org/package/config

答案 23 :(得分:0)

我在这里尝试了一些建议的解决方案,但对它们并不满意,所以我创建了自己的模块。它被称为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

答案 24 :(得分:0)

很长一段时间,我过去常常使用解决方案中提到的方法。然而,关于明文的秘密安全性存在担忧。您可以在config之上使用另一个包,以便处理安全位。

检查出来:https://www.attosol.com/secure-application-secrets-using-masterkey-in-azure-key-vault/

答案 25 :(得分:0)

我们如何使用 TypeScript 做到这一点。

export const loadConfig = () => {
    const configLoadeded = configLoader.util.toObject() as any
    Config = configLoadeded
}

export interface ConfigI {
    productName: string;
    productId: string;
    googleCloudApiKey: string;
}

答案 26 :(得分:0)

有点晚(仅 10 年),但我使用的 for (int i = 0; i < p; i++) { if (matchValue.equals(rolodex[i][0])) { System.out.println("Match Found!"); System.out.println(rolodex[i][1]); break; } else if (i == (p - 1)) { System.out.println("Match not found!"); } } 结构如下:

config.js

然后我加载配置:

const env = process.env.NODE_ENV || 'development';

var config_temp = {
    default:{
        port: 3000,
        mysql_host: "localhost",
        logging_level: 5,
        secret_api_key: process.env.SECRET_API_KEY
    },
    development: {
        logging_level: 10
    },
    production: {
        port: 3001,
        mysql_host: "not-localhost"
    }
};
var config = {
    ...config_temp.default, 
    ...config_temp[env]
}
module.exports = config;

这样:

  • var config = require('./config'); var port = config.port; 变量的读取包含在 env 文件中,因此我可以避免这种丑陋:config.js
  • 文件 require('./config')[process.env.NODE_ENV || 'development'] 可以上传到代码的 repo 中,因为敏感变量继续由 config.js 处理。
  • 如果 process.envdefault:{ 中都包含相同的元素,则只保留第二个。
  • 没有专用文件夹和多个文件(如config

答案 27 :(得分:0)

如今,在处理数据库时,最容易根本不处理配置文件,因为部署环境更容易设置,只需使用单个环境变量,例如,将其命名为 CUDNN_BENCHMARK: false DATALOADER: ASPECT_RATIO_GROUPING: true FILTER_EMPTY_ANNOTATIONS: true NUM_WORKERS: 4 REPEAT_THRESHOLD: 0.0 SAMPLER_TRAIN: TrainingSampler DATASETS: PRECOMPUTED_PROPOSAL_TOPK_TEST: 1000 PRECOMPUTED_PROPOSAL_TOPK_TRAIN: 2000 PROPOSAL_FILES_TEST: [] PROPOSAL_FILES_TRAIN: [] TEST: - layout_valid TRAIN: - layout_train GLOBAL: HACK: 1.0 INPUT: CROP: ENABLED: false SIZE: - 0.9 - 0.9 TYPE: relative_range FORMAT: BGR MASK_FORMAT: polygon MAX_SIZE_TEST: 1333 MAX_SIZE_TRAIN: 1333 MIN_SIZE_TEST: 800 MIN_SIZE_TRAIN: - 640 - 672 - 704 - 736 - 768 - 800 MIN_SIZE_TRAIN_SAMPLING: choice RANDOM_FLIP: horizontal MODEL: ANCHOR_GENERATOR: ANGLES: - - -90 - 0 - 90 ASPECT_RATIOS: - - 0.5 - 1.0 - 2.0 NAME: DefaultAnchorGenerator OFFSET: 0.0 SIZES: - - 32 - - 64 - - 128 - - 256 - - 512 BACKBONE: FREEZE_AT: 2 NAME: build_resnet_fpn_backbone DEVICE: cuda FPN: FUSE_TYPE: sum IN_FEATURES: - res2 - res3 - res4 - res5 NORM: '' OUT_CHANNELS: 256 KEYPOINT_ON: false LOAD_PROPOSALS: false MASK_ON: true META_ARCHITECTURE: GeneralizedRCNN PANOPTIC_FPN: COMBINE: ENABLED: true INSTANCES_CONFIDENCE_THRESH: 0.5 OVERLAP_THRESH: 0.5 STUFF_AREA_LIMIT: 4096 INSTANCE_LOSS_WEIGHT: 1.0 PIXEL_MEAN: - 103.53 - 116.28 - 123.675 PIXEL_STD: - 57.375 - 57.12 - 58.395 PROPOSAL_GENERATOR: MIN_SIZE: 0 NAME: RPN RESNETS: DEFORM_MODULATED: false DEFORM_NUM_GROUPS: 1 DEFORM_ON_PER_STAGE: - false - false - false - false DEPTH: 101 NORM: FrozenBN NUM_GROUPS: 32 OUT_FEATURES: - res2 - res3 - res4 - res5 RES2_OUT_CHANNELS: 256 RES5_DILATION: 1 STEM_OUT_CHANNELS: 64 STRIDE_IN_1X1: false WIDTH_PER_GROUP: 8 RETINANET: BBOX_REG_LOSS_TYPE: smooth_l1 BBOX_REG_WEIGHTS: &id001 - 1.0 - 1.0 - 1.0 - 1.0 FOCAL_LOSS_ALPHA: 0.25 FOCAL_LOSS_GAMMA: 2.0 IN_FEATURES: - p3 - p4 - p5 - p6 - p7 IOU_LABELS: - 0 - -1 - 1 IOU_THRESHOLDS: - 0.4 - 0.5 NMS_THRESH_TEST: 0.5 NORM: '' NUM_CLASSES: 80 NUM_CONVS: 4 PRIOR_PROB: 0.01 SCORE_THRESH_TEST: 0.05 SMOOTH_L1_LOSS_BETA: 0.1 TOPK_CANDIDATES_TEST: 1000 ROI_BOX_CASCADE_HEAD: BBOX_REG_WEIGHTS: - - 10.0 - 10.0 - 5.0 - 5.0 - - 20.0 - 20.0 - 10.0 - 10.0 - - 30.0 - 30.0 - 15.0 - 15.0 IOUS: - 0.5 - 0.6 - 0.7 ROI_BOX_HEAD: BBOX_REG_LOSS_TYPE: smooth_l1 BBOX_REG_LOSS_WEIGHT: 1.0 BBOX_REG_WEIGHTS: - 10.0 - 10.0 - 5.0 - 5.0 CLS_AGNOSTIC_BBOX_REG: false CONV_DIM: 256 FC_DIM: 1024 NAME: FastRCNNConvFCHead NORM: '' NUM_CONV: 0 NUM_FC: 2 POOLER_RESOLUTION: 7 POOLER_SAMPLING_RATIO: 0 POOLER_TYPE: ROIAlignV2 SMOOTH_L1_BETA: 0.0 TRAIN_ON_PRED_BOXES: false ROI_HEADS: BATCH_SIZE_PER_IMAGE: 512 IN_FEATURES: - p2 - p3 - p4 - p5 IOU_LABELS: - 0 - 1 IOU_THRESHOLDS: - 0.5 NAME: StandardROIHeads NMS_THRESH_TEST: 0.5 NUM_CLASSES: 8 POSITIVE_FRACTION: 0.25 PROPOSAL_APPEND_GT: true SCORE_THRESH_TEST: 0.05 ROI_KEYPOINT_HEAD: CONV_DIMS: - 512 - 512 - 512 - 512 - 512 - 512 - 512 - 512 LOSS_WEIGHT: 1.0 MIN_KEYPOINTS_PER_IMAGE: 1 NAME: KRCNNConvDeconvUpsampleHead NORMALIZE_LOSS_BY_VISIBLE_KEYPOINTS: true NUM_KEYPOINTS: 17 POOLER_RESOLUTION: 14 POOLER_SAMPLING_RATIO: 0 POOLER_TYPE: ROIAlignV2 ROI_MASK_HEAD: CLS_AGNOSTIC_MASK: false CONV_DIM: 256 NAME: MaskRCNNConvUpsampleHead NORM: '' NUM_CONV: 4 POOLER_RESOLUTION: 14 POOLER_SAMPLING_RATIO: 0 POOLER_TYPE: ROIAlignV2 RPN: BATCH_SIZE_PER_IMAGE: 256 BBOX_REG_LOSS_TYPE: smooth_l1 BBOX_REG_LOSS_WEIGHT: 1.0 BBOX_REG_WEIGHTS: *id001 BOUNDARY_THRESH: -1 CONV_DIMS: - -1 HEAD_NAME: StandardRPNHead IN_FEATURES: - p2 - p3 - p4 - p5 - p6 IOU_LABELS: - 0 - -1 - 1 IOU_THRESHOLDS: - 0.3 - 0.7 LOSS_WEIGHT: 1.0 NMS_THRESH: 0.7 POSITIVE_FRACTION: 0.5 POST_NMS_TOPK_TEST: 1000 POST_NMS_TOPK_TRAIN: 1000 PRE_NMS_TOPK_TEST: 1000 PRE_NMS_TOPK_TRAIN: 2000 SMOOTH_L1_BETA: 0.0 SEM_SEG_HEAD: COMMON_STRIDE: 4 CONVS_DIM: 128 IGNORE_VALUE: 255 IN_FEATURES: - p2 - p3 - p4 - p5 LOSS_WEIGHT: 1.0 NAME: SemSegFPNHead NORM: GN NUM_CLASSES: 54 WEIGHTS: /content/drive/MyDrive/layout/resnext101.pth OUTPUT_DIR: ./output SEED: -1 SOLVER: AMP: ENABLED: false BASE_LR: 8.0e-06 BIAS_LR_FACTOR: 1.0 CHECKPOINT_PERIOD: 2000 CLIP_GRADIENTS: CLIP_TYPE: value CLIP_VALUE: 1.0 ENABLED: false NORM_TYPE: 2.0 GAMMA: 0.1 IMS_PER_BATCH: 2 LR_SCHEDULER_NAME: WarmupMultiStepLR MAX_ITER: 25000 MOMENTUM: 0.9 NESTEROV: false REFERENCE_WORLD_SIZE: 0 STEPS: - 210000 - 250000 WARMUP_FACTOR: 0.001 WARMUP_ITERS: 1000 WARMUP_METHOD: linear WEIGHT_DECAY: 0.0001 WEIGHT_DECAY_BIAS: 0.0001 WEIGHT_DECAY_NORM: 0.0 TEST: AUG: ENABLED: false FLIP: true MAX_SIZE: 4000 MIN_SIZES: - 400 - 500 - 600 - 700 - 800 - 900 - 1000 - 1100 - 1200 DETECTIONS_PER_IMAGE: 100 EVAL_PERIOD: 0 EXPECTED_RESULTS: [] KEYPOINT_OKS_SIGMAS: [] PRECISE_BN: ENABLED: false NUM_ITER: 200 VERSION: 2 VIS_PERIOD: 0 ,并且根据需要向其传递任何其他配置数据。

配置数据示例:

DB_CONNECTION

创建一个连接字符串,带有数据库驱动不关心的额外参数:

const config = {
    userIds: [1, 2, 3],
    serviceLimit: 100,
    // etc., configuration data of any complexity    
};
// or you can read it from a config file

然后我们可以生成结果字符串以将其存储在环境中:

import {ConnectionString} from 'connection-string';

const cs = new ConnectionString('postgres://localhost@dbname', {
    user: 'user-name',
    password: 'my-password',
    params: {
        config
    }  ​
});

因此您将其存储在您的环境中,例如 cs.toString(); //=>postgres://localhost:my-password@dbname?config=%7B%22userIds%22%3A%5B1%2C2%2C3%5D%2C%22serviceLimit%22%3A100%7D ,并且在客户端进程中您可以通过 DB_CONNECTION 读取它:

process.env.DB_CONNECTION

通过这种方式,您将同时拥有连接和所需的所有额外配置,所有这些都在一个环境变量中,无需弄乱配置文件。