Как хранить настройки/конфигурационные файлы развертывания Node.js?

Я работаю над несколькими приложениями Node, и я искал хороший шаблон для хранения настроек, связанных с развертыванием. В мире Django (откуда я родом) общепринятой практикой было бы иметь файл settings.py, содержащий стандартные настройки (часовой пояс и т.д.), а затем файл local_settings.py для специфических настроек развертывания, т.е. к какой базе данных обращаться, какой сокет memcache, адрес электронной почты для администраторов и так далее.

Я искал похожие шаблоны для Node. Просто файл конфигурации был бы хорош, так что его не нужно вставлять в app.js вместе со всем остальным, но я считаю важным иметь возможность конфигурировать специфичные для сервера настройки в файле, который не находится в контроле исходного кода. Одно и то же приложение вполне может быть развернуто на разных серверах с дико разными настройками, и необходимость разбираться с конфликтами слияния и всем прочим - это не мое представление о веселье.

Так есть ли какой-то фреймворк/инструмент для этого, или каждый просто собирает что-то сам?

Комментарии к вопросу (1)

Я использую 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_host, config.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 для установки пакетов. Больше информации об этом [здесь] (http://howtonode.org/introduction-to-npm).

Проект хранится на GitHub, а для моего рабочего сервера добавлены пульты.

Комментарии (18)

Вы можете требовать файлов JSON в качестве узла в v0.5.х (ссылки этот ответ)

конфиг.в JSON:

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

app.js:

var config = require('./config.json');
log_in(config.username, config.password);
Комментарии (3)
Решение

Гораздо позже я нашел довольно хороший модуль 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 на Github.

Комментарии (15)

Мое решение довольно простое:

Нагрузки среды config в ./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)

Вы также можете посмотреть на dotenv, в соответствии с принципами двенадцати факторов приложение.

Я использовал, чтобы использовать Node-config, но созданные dotenv по этой причине. Он был полностью вдохновлен Руби'библиотека dotenv С.

Использование довольно простое:

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

Тогда вы просто создать .файл env и поставить свои настройки в так:

S3_BUCKET=YOURS3BUCKET
SECRET_KEY=YOURSECRETKEYGOESHERE
OTHER_SECRET_STUFF=my_cats_middle_name

Что'ы dotenv для nodejs.

Комментарии (4)

Вы, ребята, с помощью npm, чтобы запустить свои скрипты (ОКР и т. д.) ?

Если вы используете .файлы env вы можете включить их в пакете.формат 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 start-dev

Его описали здесь https://gist.github.com/ericelliott/4152984 Все кредиты Эрик Эллиот

Комментарии (4)

Вы также можете посмотреть node-config, который загружает конфигурационный файл в зависимости от переменных $HOST и __$NODE_ENV__ (немного похоже на RoR) : documentation.

Это может быть полезно для различных настроек развертывания (development, test или production).

Комментарии (0)

Просто делать простые settings.jsсэкспорт`:

exports.my_password = 'value'

Затем, в ваш скрипт, сделать требуют:

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

Все настройки теперь будет доступно через "настройки" переменной:

settings.my_password // 'value'
Комментарии (2)

Я'м собираюсь бросить свою шляпу на ринг здесь, потому что ни один из этих ответов решить все важные компоненты, что практически любой системы должен. Соображения:

  • Конфигурации публичных (которые можно увидеть на сайте) против собственной конфигурации (парень мограби получил это право). И сделать это отдельно.
  • Секреты, как ключи
  • По умолчанию против конкретной среды переопределяет
  • Связки фронтэнд

Здесь's, как я делаю свою конфигурацию:

  • `config.default.private.js - в систему управления версиями, эти параметры настройки по умолчанию, которые можно увидеть только на серверной части.
  • `config.default.public.js - в систему управления версиями, эти параметры настройки по умолчанию, которые можно увидеть на бэкэнд и фронтэнд
  • `config.dev.private.js Если вам нужны различные частные значения по умолчанию для Дев.
  • `config.dev.public.js Если вам нужны различные государственные дефолты для Дев.
  • config.private.js - не в системе контроля версий, это среда конкретных вариантов, которые переопределяютconfig.default.private.js`
  • config.public.js - не в системе контроля версий, это среда конкретных вариантов, которые переопределяютconfig.default.public.js`
  • ключей - папка, в которой каждый файл хранит различные секрет какой-то. Это тоже не под контролем версий (ключи никогда не должны быть под контролем версий).

Я использую обычный старый JavaScript-файлы конфигурации, так что я имею полное власть на JavaScript язык (в том числе комментарии и возможность делать вещи, как загрузить дефолтовый конфиг файл в среде конкретного файла, так что они могут быть переопределены). Если вы хотите использовать переменные окружения, вы можете загрузить их в этих конфигурационных файлах (хотя я рекомендую использовать переменные окружения по этой же причине я не'т рекомендуем использовать JSON файлы - вы Дон'т иметь мощь языка программирования, чтобы создать свой конфиг).

Причина каждый ключ в отдельном файле предназначен для использования установщика. Это позволяет иметь установки, что создает ключи на машину и сохраняет их в папке ключи. Без этого, ваш установщик может привести к ошибке при загрузке файла конфигурации, который может'т получить доступ к вашим ключам. Таким образом, вы можете пройти в каталог и загружать любые файлы ключей, которые находятся в этой папке, не беспокоясь о том, что существует и то, что не'т в какой-либо определенной версии вашего кода.

Поскольку вы, вероятно, есть ключи загружаются в ваши личные настройки, вы наверняка Дон'т хотите загрузить свой собственный конфиг в любой фронтенд код. Хотя его, вероятно, строго необходимое, чтобы полностью отделить интерфейс от кода серверной части, много раз, что лаваш-это достаточно большой барьер, чтобы помешать людям делать это, таким образом, личное против общественного конфигурации. Но там'ы две вещи, которые я сделать, чтобы предотвратить частная конфигурации, загруженной в интерфейсе:

  1. У меня есть unit-тест, который обеспечивает мой фронтэнд связки Дон'т содержать один из секретных ключей у меня в отдельный конфиг.
  2. У меня есть код фронтэнда в другой папке, чем мой код серверной части, а у меня два разных файлов по кличке "конфиг.Яш" по - одному на каждый конец. Для бэкэнда, config.js загружает индивидуальный конфиг для фронтэнда, он загружает общественного конфигурации. Тогда вы всегда просто требуют('конфигурации') и Дон'т беспокоиться о том, где оно происходит от.

Одна последняя вещь: ваша конфигурация должна быть загружена в браузер через полностью отдельный файл, чем любой из ваших других код фронтэнда. Если вы связать ваш код фронтэнда, общественного конфигурации должен быть построен как полностью отдельный пакет. В противном случае, ваш конфиг это'т действительно конфиг больше - его только часть вашего кода. Конфиг должен уметь быть разным на разных машинах.

Комментарии (2)

Каторжник еще один вариант, который добавляет схему для проверки. Как nconf, он поддерживает параметры загрузки из любой комбинации переменных окружения, аргументы, файлов и объектов JSON.

Пример из readme:

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"
  }
});

Начало статьи: Укрощение конфигураций с node-convict

Комментарии (0)

Вы можете использовать конфиг для конкретных условий конфигурационных файлов. Он загружает JSON или YAML config автоматически файлов, он имеет значение по умолчанию и динамические характеристики конфигурации.

Пример из конфиг РЕПО:

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=производство порт=4567 узел app.js`

> config.app.port
4567

Более детально : https://github.com/vngrs/konfig

Комментарии (0)

Я создам папку как конфиг файл именования как 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'
    }
}

Тогда, если я хочу использовать где-то этот конфигурационный файл

Я сначала импортировать как ниже

ВАР конфиг = требуют('./конфигурация');

и я могу получить доступ к значениям, как показано ниже

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');
    }
});
Комментарии (0)

Просто используйте НПМ модуль конфигурации (более 300000 загрузок)

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

Узел-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
Комментарии (0)

Это's лучше, чтобы отделить 'развития' и 'производства' конфиги.

Я использую следующим образом: Вот мой 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;
Комментарии (1)

Я немного поздно в игре, но я не мог'т найти то, что мне нужно здесь - или нигде - поэтому я написал что-то сам.

Мои требования для механизма конфигурации являются следующие:

  1. Поддержка фронтальный. Какой смысл, если передний конец не может использовать конфигурацию?
  2. Поддержка settings-overrides.js- который выглядит так же, но позволяет переопределения конфигурации в settings.js. Идея здесь легко изменять конфигурацию без изменения кода. Я считаю это полезным для ЗАС.

Хотя мне плевать, поддерживающих средах - объясню, как легко добавить его на мое решение

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;

Объяснение

  • неопределенный означает, что это свойство является обязательным
  • "нулевой" означает, что это необязательно
  • meConf - в настоящее время код целевой файл приложение. meConf - это переопределяет файлов, который предназначен для `Conf в каталоге/dev, которые игнорируют мои СКВ.
  • publicConfiguration - будет видно из фронт-энд и бэк-энд.
  • privateConfiguration - будет виден только.
  • sendPublicConfiguration - маршрут, который будет подвергать открытую конфигурацию и присвоить его глобальной переменной. Например, приведенный ниже код будет подвергать общественного конфигурации как глобальная переменная myConf в переднем конце. По умолчанию он будет использовать глобальную переменную имя conf и.

приложение.вам (и" и quot/серверной/конф&;, требуют (и"конф и").sendPublicConfiguration);

<скрипт в src=" и/серверной/конф?имя=myConf" и тип="и на JavaScript/текст" и>

Логика перекрывает

  • privateConfiguration сливается с publicConfiguration, а затем meConf.
  • publicConfiguration проверяет каждый ключ, если его переопределить, и использует это переопределить. Таким образом, мы не выставляя ничего частного.

Добавление поддержки окружающей среды

Хотя я Дон'т найти "в поддержку окружающей среды" не полезна, может кто-то.

Чтобы добавить поддержку окружающей среды необходимо изменить meConf требуют заявление что-то вроде этого (псевдокод)

если ( окружающая среда = = на "постановку" ) { meConf = требуют (и"../Conf в каталоге/dev/meConf и").производства; }

если ( окружающая среда = = на "Развитие", у ) { meConf = требуют (и"../Conf в каталоге/dev/meConf и").развития; }

Аналогичным образом вы можете иметь файл в среде

 meConf.development.js
 meConf.production.js

и импорт правильным. Остальная логика остается той же.

Комментарии (2)

азц примере я просто использовал, потому что я хотел больше гибкости, чем обычно .JSON-файл, но ничего'т хотим, чтобы это абстрагированные в библиотеку, которая потребует зависимость-это что-то вроде этого. В основном, экспорт функция автоматически вызывается, который возвращает объект со значениями, я хотел установить. Дает большую гибкость.

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

Есть гораздо лучшее объяснение с полный пример здесь. Использование конфигурационных файлов в Node.js

Комментарии (0)

Я знаю, что это очень старый пост. Но я хочу поделиться своим модулем для настройки переменных окружения, я думаю, что это очень гибкое решение. Здесь-модуль в JSON-конфигуратор

var configJson = {
  'baseUrl': 'http://test.com',
  '$prod_baseUrl': 'https://prod.com',
  'endpoints': {
    'users': '/users',
    'accounts': '/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 

Затем вы можете использовать процесс.ОКР.Переменной NODE_ENV, чтобы получить все переменные среды.

Комментарии (1)

В дополнение к nconf Модуль упоминалось в этот ответ, и узел-конфигурации, упомянутые в этот ответ, также узел-iniparser и IniReader, которые кажутся проще .конфигурации ini парсеров.

Комментарии (1)

Я только недавно выпустила небольшой модуль для загрузки любого типа файлов конфигурации. Это'ы довольно прямо вперед, вы можете проверить его на https://github.com/flesler/config-node

Комментарии (0)

Вы можете использовать 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

}
Комментарии (0)