Как сохранить файлы настроек / конфигурации Node.js? - PullRequest
606 голосов
/ 03 мая 2011

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

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

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

Ответы [ 23 ]

739 голосов
/ 03 мая 2011

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

231 голосов
/ 04 февраля 2013

Вам могут потребоваться файлы JSON с Node v0.5.x (, ссылающиеся на этот ответ )

config.json:

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

app.js:

var config = require('./config.json');
log_in(config.username, config.password);
189 голосов
/ 19 декабря 2011

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

85 голосов
/ 27 ноября 2012

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

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

31 голосов
/ 30 апреля 2014

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

Я использовал для использования node-config, но создал dotenv дляэта причина.Она полностью вдохновлена ​​библиотекой ruby's dotenv.

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

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

Затем вы просто создаете файл .env и вносите в него свои настройки следующим образом:

S3_BUCKET=YOURS3BUCKET
SECRET_KEY=YOURSECRETKEYGOESHERE
OTHER_SECRET_STUFF=my_cats_middle_name

Это dotenv для nodejs.

29 голосов
/ 23 октября 2013

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

22 голосов
/ 23 апреля 2012

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

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

20 голосов
/ 27 января 2013

Просто сделайте простое settings.js с exports:

exports.my_password = 'value'

Затем в вашем скрипте выполните require:

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

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

settings.my_password // 'value'
12 голосов
/ 02 марта 2017

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

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

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

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

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

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

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

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

11 голосов
/ 03 февраля 2014

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

Пример из репозитория Konfig:

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

...