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

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

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

Итак, есть ли какая-то структура/инструмент для этого, или все просто взломали что-то вместе?

Ответ 1

Значительно позже я нашел довольно хороший 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.

Ответ 2

Я использую 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 для установки пакетов. Подробнее об этом здесь.

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

Ответ 3

Вы можете потребовать файлы JSON с Node v0.5.x(ссылкой на этот ответ)

config.json:

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

app.js:

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

Ответ 4

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

Загрузите конфигурацию среды в. /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/

Ответ 5

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

Я использовал 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

Это dotenv для nodejs.

Ответ 6

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

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

Ответ 7

Вы, ребята, используете 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 Весь кредит Эрику Эллиоту

Ответ 8

Просто выполните settings.js с exports:

exports.my_password = 'value'

Затем в script сделайте a require:

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

Теперь все ваши настройки будут доступны через переменную settings:

settings.my_password // 'value'

Ответ 9

Convict - еще одна опция, которая добавляет схему для проверки. Как и 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

Ответ 10

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

Пример из 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

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

  • Общественная конфигурация (которая может быть видна интерфейсом) против частной конфигурации (парень mograbi получил это право). И обеспечить их сохранение отдельно.
  • Секреты, такие как клавиши
  • Значение по умолчанию vs переопределения, относящиеся к среде
  • Фронтальные пакеты

Вот как я делаю свою конфигурацию:

  • config.default.private.js - В управлении версиями это параметры конфигурации по умолчанию, которые можно увидеть только на вашем сервере.
  • config.default.public.js - В управлении версиями это параметры конфигурации по умолчанию, которые можно увидеть с помощью backend и frontend
  • 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 langauge (включая комментарии и возможность делать такие вещи, как загрузка файла конфигурации по умолчанию в файл, относящийся к среде, чтобы затем их можно было переопределить), Если вы хотите использовать переменные среды, вы можете загружать их внутри этих файлов конфигурации (я рекомендую не использовать env vars по той же причине, что и я не рекомендую использовать json файлы - у вас нет возможности языка программирования для построения ваш конфиг).

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

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

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

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

Ответ 12

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

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

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

Ответ 13

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

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

  • Поддержка интерфейса. В чем смысл, если интерфейс не может использовать конфигурацию?
  • Поддержка 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;

Описание

  • 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 на что-то вроде этого (псевдокод)

if (environment == "production" ) {       meConf = require ( "../conf/dev/meConf" ); производство;  }

if (environment == "development" ) {       meConf = require ( "../conf/dev/meConf" );  }

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

 meConf.development.js
 meConf.production.js

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

Ответ 14

Я знаю, что это действительно старый пост. Но я хочу поделиться своим модулем для настройки переменных среды, я думаю, что это очень гибкое решение. Вот модуль 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, чтобы получить все переменные для вашей среды.

Ответ 16

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

Ответ 17

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

}

Ответ 18

Для тех, кто посещает этот старый поток, вот пакет, который я считаю хорошим.

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

Ответ 19

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

Вы сохраняете свою конфигурацию в виде простых js или json файлов из папки /config. Сначала он загружает файл 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

Ответ 20

В течение долгого времени я использовал подход, упомянутый в решении здесь. Однако существует озабоченность по поводу безопасности секретов в ясном тексте. Вы можете использовать другой пакет поверх config, чтобы обеспечить защиту битов безопасности.

Проверьте это: https://www.attosol.com/secure-application-secrets-using-masterkey-in-azure-key-vault/