Best way to store DB config in Node.Js / Express app

Javascriptnode.jsExpressConfig

Javascript Problem Overview


What would be the best way to store DB config (username, password) in an open source app that runs on node.js / Express? Two specific questions:

  1. Shall I put it into a separate config.js file in /lib folder, for example, and never include it into the master repository that is publicly available on GitHub?

  2. To inlcude the config, is it as simple as require('./config.js') from the file that needs it or is there a better way of doing it?

PS sorry if the questions seem a bit simple or not so well formulated, but I'm just starting :)

Javascript Solutions


Solution 1 - Javascript

Here's how I do it:

Create a config.js which contains objects representing your configs:

var config = {
development: {
	//url to be used in link generation
	url: 'http://my.site.com',
	//mongodb connection settings
	database: {
		host:	'127.0.0.1',
		port:	'27017',
		db:		'site_dev'
	},
	//server details
	server: {
		host: '127.0.0.1',
		port: '3422'
	}
},
production: {
	//url to be used in link generation
	url: 'http://my.site.com',
	//mongodb connection settings
	database: {
		host: '127.0.0.1',
		port: '27017',
		db:		'site'
	},
	//server details
	server: {
		host:	'127.0.0.1',
		port:	'3421'
	}
}
};
module.exports = config;

Then in my index.js (or wherever really),

var env = process.env.NODE_ENV || 'development';
var config = require('./config')[env];

Then process with that object, e.g.

var server = express();
server.listen(config.server.port);
...

Solution 2 - Javascript

For running toy apps where I need to hide db credentials, I use the dotenv module.

Place your sensitive info in a .env file (which is .gitignored), place require('dotenv').config(); in your app; dotenv creates entries in process.env that you can refer to.

.env file:

DATABASE_PASSWORD=mypw
DATABASE_NAME=some_db

To refer to the values:

process.env.DATABASE_PASSWORD

Solution 3 - Javascript

Not sure whether this is the best practice, but personally I have a config.json file where I store my db connection information. Then I do the following:

// options.js
var fs = require('fs'),
configPath = './config.json';
var parsed = JSON.parse(fs.readFileSync(configPath, 'UTF-8'));
exports.storageConfig=  parsed;

Then from a different file I do the following:

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

var loginData = {
        host: options.storageConfig.HOST,
        user: options.storageConfig.user,
        password: options.storageConfig.password
};

Solution 4 - Javascript

I do put in args. just like the port of so many node.js example. you most likely forever, pm2, nodemon to run your app. so this variable is not check in as part of your source code. and they are globally available too.

process.env.PORT
process.env.DATABASE_USER
process.env.DATABASE_PASSWORD


PORT=3000 DATABASE_HOST=localhost DATABASE_USER=admin DATABASE_PASSWORD=mypassword node app.js

export PORT=3000
export DATABASE_HOST=localhost
export DATABASE_PORT=27017
export DATABASE_USER=admin
export DATABASE_PASSWORD=mypassword
node app.js

var server = app.listen(process.env.PORT, function() {
});

var mongoClient = new MongoClient(new Server(process.env.DATABASE_HOST, process.env.DATABASE_PORT));

Solution 5 - Javascript

> To inlcude the config, is it as simple as require('./config.js') from the file that needs it or is there a better way of doing it?

This is the right way to store config files.

The best approach would be to write your entire application like an ordinary node.js module, and write a small start-up file that calls it. This idea also allow you to use different database drivers using dependency injection.

Good, but not perfect solution is the environment. It is shared among all application, so if you have certain data you want to be available to all of them, this is the best bet. But if you have a config for one particular app, not much so.

PS: And please, don't use JSON for this. It's the worst idea possible. :)

Solution 6 - Javascript

I found this a nice way to handle my config, considering different environments:

config.coffee

exports.setEnvironment = (env) ->
    switch env
    	when "development"
    		exports.DEBUG_LOG = true
    		exports.DB_PORT = '27017'
            # ...
    	when "testing"
    		exports.DEBUG_ERROR = true
    		exports.DEBUG_CLIENT = true
            # ...
    	when "production"
    		exports.DEBUG_LOG = false
            # ...
    	else console.log "environment #{env} not found"

server.coffee:

config = require('./config')
config.setEnvironment env

Solution 7 - Javascript

  1. Using environment variables

You can use export to set environment variables in OSX and Linux. The following is an example of setting a value in the SESSION_SECRET key.

export SESSION_SECRET="keyboard cat"

In Windows, you can use set.

set SESSION_SECRET="keyboard cat"

You can also set environment variables each time you run them.

SESSION_SECRET="keyboard cat" node secret-env.js

Use process.env of node.js to access environmental variables within code.

var express = require('express')
var session = require('express-session')
var app = express()
app.use(session({secret: process.env.SESSION_SECRET}))
  1. Request a argument from the command-line

The best way to protect confidential information is not to store it in a setup file. If the command-line requests configuration information as an argument using the noopt package, the secret information does not need to exist as a file. The following is an example of requesting a session key as an argument using the noopt package.

var nopt = require("nopt")

var longOpts = {
  "sessionSecret": String,
}

var shortOpts = {
  "s": ["--sessionSecret"],
}

var parsed = nopt(longOpts, shortOpts, process.argv, 2)

console.log("session secret is:", parsed.sessionSecret)
node secret-arg.js --sessionSecret "keyboard cat"
node secret-arg.js -s "keyboard cat"

Advantages : It is safer to expose confidential information than to hardcoding or having it as a configuration file.

Disadvantages : There is a hassle of increasing the amount of information to be entered each time the app is launched. If you try to create and solve a script, the problem that the password still exists in the script remains.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionAerodynamikaView Question on Stackoverflow
Solution 1 - JavascriptStephen WrightView Answer on Stackoverflow
Solution 2 - JavascriptRobb BroomeView Answer on Stackoverflow
Solution 3 - JavascriptanvarikView Answer on Stackoverflow
Solution 4 - JavascriptwayneView Answer on Stackoverflow
Solution 5 - JavascriptalexView Answer on Stackoverflow
Solution 6 - JavascriptFlaudreView Answer on Stackoverflow
Solution 7 - JavascriptJongSun ParkView Answer on Stackoverflow