7

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

21

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

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

Существует ли какой-либо фреймворк или инструмент для этой задачи, или все просто придумывают что-то на ходу?

5 ответ(ов)

1

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

Загрузите конфигурацию окружения в файле ./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';

// MongoDB
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

Таким образом, вы сможете легко переключаться между различными конфигурациями окружения, что удобно для тестирования и разработки.

0

Если вы используете файлы .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 run start-dev

Дополнительную информацию можно найти здесь: https://gist.github.com/ericelliott/4152984. Все кредиты Эрику Эллиоту.

0

Просто создайте простой файл settings.js с использованием exports:

exports.my_password = 'value';

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

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

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

settings.my_password; // 'value'
0

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

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

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

  • 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.
  • keys/ — папка, где каждый файл хранит разные секреты. Это также не подлежит контролю версий (секреты никогда не должны находиться под контролем версий).

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

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

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

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

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

0

Вы можете создать папку для конфигурационных файлов и создать файл с именем config.js, который затем будете использовать в своем проекте. Вот пример того, как может выглядеть файл config.js:

module.exports = {
    proxyURL: 'http://url:port',
    TWITTER: {
        consumerkey: 'вашconsumerkey',
        consumerSecrete: 'вашconsumersecrete'
    },
    GOOGLE: {
        consumerkey: 'вашconsumerkey',
        consumerSecrete: 'вашconsumersecrete'
    },
    FACEBOOK: {
        consumerkey: 'вашconsumerkey',
        consumerSecrete: 'вашconsumersecrete'
    }
}

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

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

После этого вы сможете получить доступ к значениям из файла config.js, как показано ниже:

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

Таким образом, вы можете удобно управлять конфигурациями вашего приложения, сохраняя их в одном месте.

Чтобы ответить на вопрос, пожалуйста, войдите или зарегистрируйтесь