Best practice to use a configuration file for Paths, Ports, - node.js

I have to update and optimize an nodejs Project for some new use cases. For this, i have to easily change the paths for different host systems. Till now they were hardcoded.
First i used global variables, just to get the system running. But globals are not a very clever idea. Now i created a config.js file which includes the paths and in any nodejs file i linked to them with request("config.js").
nodejs
`global.OEM_datapath = __dirname + '/public/data.csv';
now:
config.js
var PATHs = {
'OEM_datapath': __dirname + '/public/data/data.csv'
}
module.exports = PATHs;
other nodejs files:
var globals = require('./config');
console.log("path:" + globals.OEM_datapath);
'''
Is there a better way to use configuration settings? I considered to use process.env?

Node.js is an environment that helps you create server-side applications using JavaScript. One of the common Node.js elements that developers like and use are .env files. These files let you easily save and load environment variables. Developers often use them to store confidential information. However, sometimes they forget to disable access to these files from the outside, which can lead to major security problems. You can create a sperate env file and maintain the dynamic values.

I considered to use process.env
That is the standard way, in fact if you are working with containers, such as Docker this will also be the case. My suggestion would be to use YAML as the config language and derive config from that, again a Docker 'standard'.

Related

NodeJs Environment variables vs config file

Actually I have a nodejs express app with its config file for params like host, port, JWT token, DB params and more.
The question is if it could have sense to keep those params directly on environment variables (whitout any config file) and acces them without the need of do the "require" for config in all components and modules.
All examples I see uses a config file, probably something about security or memory?
config file is usually for setting the default values for your environment variables,
which is needed when you are writing the test cases and need to use default values or mock values,
and also you will have all the env variables at one place which is better management.
so if you have an environment variable x,
in config file you can keep it as
config.x = process.env.x || 'defaultVale or mockValue'
A config file lets your very quickly set the entire environment of a machine - eg S3 buckets, API urls, access keys, etc. If you separate these into separate process.env.VARIABLE then you would need to set each of these...for which you would likely make a script...and now you have an environment file again!
To access environment variables you can use process.env.VARIABLE in your nodejs code (is always a string), as long as the variable is set before the process is started.
Another possibility is using an .env files in nodejs. I think you have to npm install dotenv in your application. Ideally different instances (dev, prod....) have its own .env file, and you dont have to call require("dotenv") every time if you want to access the environment variable. Call it in the very beginning i.e) in app.js and you can access the environment variable in any of the sub-files.

Add multiple users to node JS env file

I have a nodeJS application. In the .env file I have specified
AUTH_USERNAME=admin
AUTH_PASSWORD=password
I now want to add separate admin accounts for more users. What is the best/accepted way to attack this? I have tried searching on the topic but, understandably, it gets very complicated very quickly - can anyone give me a dummies guide for my possibilities here?
Thanks.
The solution in your case without changing approach where to store credentials is use separator in environment variables. Example with , as separator:
#.env file or environment variables values
AUTH_USERNAMES=admin,admin2
AUTH_PASSWORDS=password,password2
//your code
require('dotenv').config(); // for reading .env file or how do you use that
const adminsUsernames = process.env.AUTH_USERNAMES.split(',');
const adminsPasswords = process.env.AUTH_PASSWORDS.split(',');
Please, think about change .env file to database or config.json file. Maybe, this list will help you:
obviously, you received downvotes on your question, because of non-common approach where to store credentials. Common approach is store credentials at database.
according The Twelve Factors manifest environment variables are
used for configuration whole application.
.env is used for simplification setting environment variables during local development. In production DevOps setup env vars on the server.

How to set process.env from the file in NodeJS?

I'm new to the Node.JS. I found few articles says we can use .env file to setup the process.env variable, e.g.,
PORT = 8081
but when I run the program in my node, it is still 8080 PORT (by default). The question is how can I setup the env variable in Node without any other 3rd party module's help? (I found there are few 3rd party package to management the env config, but... it is kind confused, different package might have different rule and more complex use cases; I want to start from clear way to study purely nodejs)
Update
I have read Node Environment Setting post on StackOverFlow, but they are refer using 3rd party package, none of them tells the detail steps. (Either windows system environment, or Linux environment variables... but how can I place the setting into my project folder?!)
Dotenv file have become the most popular mode to separate configuratione from app, using system environment variables (see 12factor config).
On node there exists a lot of libraries for loading config from .env file. The most popular is motdotla/dotenv.
You can read a lot of examples on readme file about the usage of this library
Make a config.js file with the following content:
module.exports = {
bar: 'someValue',
foo: 'otherValue'
...
}
Then you can do this in some file:
const config = require('./config');
let foo = config.foo;

Where should I store secret strings on Node server?

Well, I've come with a problem. How can I store passwords, db url and important strings that should not go to my public version control?
I've come up with 3 solutions. The first works only on dev:
var config = require('./config');
var port = config.serverPort;
config.js
module.exports = {
'serverPort' : '8182'
}
The second one should work both on dev and prod. But the config.js file was added on the .gitignore file, so it won't be upload to the server. When the server tries to require config.js and can't find it, it will throw an error.
var config = require('./config');
var port = process.env.PORT || config.serverPort;
The third is to use only process.env variables, but this only works on production. And, if I'm testing on local machine, I may need to paste my secret strings and remember to remove it before sending to the public version control.
So, what should I do?
The common solution is to add a config.js.example file to version control (that contains empty/dummy values to document what's available).
Then you add config.js to .gitignore (or whatever suits your VCS).
To run your application you simply copy config.js.example to config.js and put in the proper values.
Of course the path to config.js can be taken from an environment variable to allow easily using different configs - but still, you wouldn't put the actual config files under version control (unless you have a separate private repo for config files etc)
It does make sense to always require a config file to exist. Even in development. While the default settings may be suitable, chances are good that many developers on your application want to configure things anyway or simply test things with non-default values.
The dotenv package can be used to load configuration and secrets from a .env file into process.env. For production, the .env file doesn't have to exist.
Example:
require('dotenv').config();
const oauth2 = require('simple-oauth2').create({
client: {
id: process.env.TWITTER_CONSUMER_KEY,
secret: process.env.TWITTER_CONSUMER_SECRET
}
});
.env file:
TWITTER_CONSUMER_KEY=bMm...
TWITTER_CONSUMER_SECRET=jQ39...
.gitignore:
.env
Here is my suggestion:
1. Using a mix of file and env variables
You can manage secret strings using a mix with config files and process.env variables.
You can do something like this:
var port = process.env.PORT || config.serverPort;
Since now, working with docker is the rule, you should try this one.
2. Using a Sample
You could add a config.json.example to your repo with an example of the variables you should define but here you will have to remember to change it when you deploy to production.
Just remember to add the real config.json to the .gitignore file.
This one is not my preferred but still an option.
There's a node package that handles this very similar to the Ruby On Rails approach with their credential system: schluessel
It lets you save your secrets in an encrypted vault file and stores the key separately. This vauft file can be checked into your version control system, as long as you keep your key file secret.
You can create vault files for different NODE_ENVs.
If you surrender the key either via a key file or via an environment variable,
you can access your credentials very easily from within your app.

How can I get the application base path from a module in Node.js?

I'm building a web application in Node.js, and I'm implementing my API routes in separate modules. In one of my routes I'm doing some file manipulation and I need to know the base app path. If I use __dirname, it gives me the directory that houses my module of course.
I'm currently using this to get the base application path (given that I know the relative path to the module from base path):
path.join(__dirname, "../../", myfilename)
Is there a better way than using ../../? I'm running Node.js under Windows, so there isn't any process.env.PWD, and I don't want to be platform-specific anyway.
The approach of using __dirname is the most reliable one. It will always give you correct directory. You do not have to worry about ../../ in Windows environment as path.join() will take care of that.
There is an alternative solution though. You can use process.cwd() which returns the current working directory of the process. That command works fine if you execute your Node.js application from the base application directory. However, if you execute your Node.js application from different directory, say, its parent directory (e.g., node yourapp\index.js) then the __dirname mechanism will work much better.
You can define a global variable like in your app.js file:
global.__basedir = __dirname;
Then you can use this global variable anywhere. Like this:
var base_path = __basedir
You can use path.resolve() without arguments to get the working directory which is usually the base application path. If the argument is a relative path then it's assumed to be relative to the current working directory, so you can write
require(path.resolve(myfilename));
to require your module at the application root.

Resources