NodeJs Environment variables vs config file - node.js

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.

Related

Handle multiple environments variables in .env NodeJs

Suppose I have a .env file like these:
#dev variable
PORT=3000
#production
PORT=3030
And I get these variables using process.env, how can I manage to sometimes use the dev variable and other times the Production variable
You can create multiple .env files like .dev.env, .prod.env, and load them based on NODE_ENV. using this
Storing configuration in environment variables is the way to go, and exactly what is recommended by the config in the 12-Factor App, so you're already starting with the right foot.
The values of these variables should not be stored with the code, except maybe the ones for your local development environment, which you can even assume as the default values:
port = process.env.PORT || '3000';
For all other environments, the values should be stored in a safe place like Vault or AWS Secrets Manager, and then are only handled by your deployment pipeline. Jenkins, for example, has a credentials plugin to handle that.

Can anyone tell me why is node not recognizing my environment variable?

I have a sendgrid API key. I placed it into a dot.env file inside a config folder.
Bud when I try to use it to set api key:
sgMail.setApiKey(process.env.SENDGRID_API_KEY);
Node keeps telling me API key does not start with "SG."
If I try to console.log(process.env.SENDGRID_API_KEY) it gives me undefined.
inside dev.env file:
SENDGRID_API_KEY=myapikey
I also have a PORT variable inside this folder and it is used without problems, so it is not a matter of a path to the file. It is not a typo either.
Are you using something like the "dotenv" package to read de environment variables from the "dev.env" file? You can't read environment variables in NodeJS without something like that if I am not mistaken. When I learned how to import this kind of variables I was teached to name the file just ".env".

Best practice to use a configuration file for Paths, Ports,

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'.

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.

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.

Resources