Setting Environment Variables for Node to retrieve
Asked Answered
I

20

548

I'm trying to follow a tutorial and it says:

There are a few ways to load credentials.

  1. Loaded from environment variables,
  2. Loaded from a JSON file on disk,

The keys need to be as follows:

USER_ID, USER_KEY

...This means that if you properly set your environment variables, you do not need to manage credentials in your application at all.

Based on some Googling, it appears that I need to set the variables in process.env? How and where do I set these credentials? Example Please.

Ignorance answered 10/3, 2014 at 22:25 Comment(0)
P
486

Environment variables (in this case) are being used to pass credentials to your application. USER_ID and USER_KEY can both be accessed from process.env.USER_ID and process.env.USER_KEY respectively. You don't need to edit them, just access their contents.

It looks like they are simply giving you the choice between loading your USER_ID and USER_KEY from either process.env or some specificed file on disk.

Now, the magic happens when you run the application.

USER_ID=239482 USER_KEY=foobar node app.js

That will pass the user id 239482 and the user key as foobar. This is suitable for testing, however for production, you will probably be configuring some bash scripts to export variables.

Pickaback answered 10/3, 2014 at 22:34 Comment(5)
If you're using fish instead of bash, you need to use: env USER_ID=239482 my_command. For example, for setting environment variables for node.js' debug library: env DEBUG='*' node some_file.js fishshell.com/docs/current/faq.html#faq-single-envEmbroil
I found I had to remove the quotes around "*" for it to work: env DEBUG=* node some_file.jsOutsider
@Pickaback how do set these variables in Ubuntu linux?Roux
is it possible to add a file rather than adding a large number of env scripts or does a unix user need to create a bash script?Sassenach
@Sassenach yes, that's what dotenv is all about, as it will read your .env file and apply it.Constitutive
H
238

I highly recommend looking into the dotenv package.

https://github.com/motdotla/dotenv

It's kind of similar to the library suggested within the answer from @Benxamin, but it's a lot cleaner and doesn't require any bash scripts. Also worth noting that the code base is popular and well maintained.

Basically you need a .env file (which I highly recommend be ignored from your git/mercurial/etc):

FOO=bar
BAZ=bob

Then in your application entry file put the following line in as early as possible:

require('dotenv').config();

Boom. Done. 'process.env' will now contain the variables above:

console.log(process.env.FOO);
// bar

The '.env' file isn't required so you don't need to worry about your app falling over in it's absence.

Herbartian answered 8/12, 2015 at 11:17 Comment(6)
Although if you do put relevant configuration details that your app requires (such as this question is inquiring about), then it likely would fall over in its absence.. but it does still seem like a good option.Keese
If you are looking for extra safety then github.com/rolodato/dotenv-safe and a few tests should do it.Herbartian
If you're looking to not have to require it in your application: github.com/direnv/direnvHydrodynamics
This means comitting your secrets in git repoMccreary
I wouldn't recommend that. This should be for your local environment only and the file should be gitignore'd. CI/CD should inject env variables for other environments.Herbartian
If someoen runs into trouble - make sure you named your file '.env'. That's the default path dotenv looks for.St
C
176

You can set the environment variable through process global variable as follows:

process.env['NODE_ENV'] = 'production';

Works in all platforms.

Clatter answered 10/2, 2016 at 14:25 Comment(13)
... environment variables are intended to be set from the outside of the code, not indside -- so this is defeating the purpose and a bad exampleNolte
@Nolte our node program that launches child process benefited from this answer, so there are use cases for this even though it's a little unorthodoxVallation
@Vallation -- I'm 99% sure you are doing it wrong and unless you are the author of a config package like this you should be using such config package instead.Nolte
This is useful if you are writing build scripts in js and running them from npmEncephalogram
This is also useful for e.g. setting and overriding the environment when running tests.Reinforcement
I agree that this is a great idea for tests but not for elsewhere.Ido
Hey @Soren, here's another interesting use case for you: I use this to set the value of NODE_ENV before I require("config") with that same package, all within the scope of a commander CLI app.. :) Now I can reference the contents of named config files using a simple CLI argument. Simple and effective.Baumgartner
This is not really effective for scripts because it only lasts for the current node session. For example, if I run this from the command line and then run echo $NODE_ENV is just returns undefined.Hairball
Found this useful for setting the HTTP_PROXY server details within node js code. Thanks!Xray
We use AWS key rotation secrets which are set asynchronously.Cachou
If already set from command line this will have no effect. Must close and restart cmd so it doesn't already exist and then this will work from the script. Is useful for playing with UV_THREADPOOL_SIZEBauxite
It was useful for Groovy script in Jenkins in my case lol, it runs a node script to interact with Jira (I know it might sound cumbersome but that's what we have) where I can't set an env var in Groovy 'execute' command (I tried but nothing works from the official docs) but can pass required env vars as cli args for node script, so used this as 'fallback' is script was called from Groovy with args instead of env vars (and avoided to rewrite the node script, by parsing args if they exist and set them as env vars).Blackfish
node program that launches child process benefited from this answer: When you launch a child process, you can pass in the env. It seems like you should avoid modifying the parent process env in that caseLecroy
M
128

Just provide the env values on command line

USER_ID='abc' USER_KEY='def' node app.js
Maun answered 10/3, 2014 at 22:40 Comment(5)
Just adding that it worked for me on Windows with bash shell (cygwin; installed with git tools I think).Dozy
@TiborSzasz: Cygwin or Powershell should fix that. This is mentioned two years later, of course.Hitandrun
For Windows use: SET USER_ID='abc'Secular
@Mike, you should make that a proper answer :)Undervalue
We can use cross-env package (npmjs.com/package/cross-env) to make it work on unix or windwosArizona
R
64

If you want a management option, try the envs npm package. It returns environment values if they are set. Otherwise, you can specify a default value that is stored in a global defaults object variable if it is not in your environment.

Using .env ("dot ee-en-vee") or environment files is good for many reasons. Individuals may manage their own configs. You can deploy different environments (dev, stage, prod) to cloud services with their own environment settings. And you can set sensible defaults.

Inside your .env file each line is an entry, like this example:

NODE_ENV=development
API_URL=http://api.domain.com
TRANSLATION_API_URL=/translations/
GA_UA=987654321-0
NEW_RELIC_KEY=hi-mom
SOME_TOKEN=asdfasdfasdf
SOME_OTHER_TOKEN=zxcvzxcvzxcv

You should not include the .env in your version control repository (add it to your .gitignore file).

To get variables from the .env file into your environment, you can use a bash script to do the equivalent of export NODE_ENV=development right before you start your application.

#!/bin/bash
while read line; do export "$line";
done <source .env

Then this goes in your application javascript:

var envs = require('envs');

// If NODE_ENV is not set, 
// then this application will assume it's prod by default.
app.set('environment', envs('NODE_ENV', 'production')); 

// Usage examples:
app.set('ga_account', envs('GA_UA'));
app.set('nr_browser_key', envs('NEW_RELIC_BROWSER_KEY'));
app.set('other', envs('SOME_OTHER_TOKEN));
Running answered 3/3, 2015 at 0:0 Comment(7)
Hmm, I tried to use this package but it seems to only track environment variable usage. It doesn't read .env file (npmjs.com/package/envs). Is it a correct package ?Magnum
You're right! It does not read the .env file. This is embarrassing. I forgot that I was loading the .env with a bash script as @Pickaback mentioned, so it worked anyway.Running
"require('envs')"? What is "envs"?Ecto
'envs' is the name of a node module: npmjs.com/package/envsRunning
Sir how to generate .env file? As filename is must so how do we create .env file in windows?Transcribe
".env" begins with a dot so that it is hidden by default on most *nix systems. This allows for basic privacy, and keeps the config out of the way while developing the app. You can name that file anything you like. I've seen environment variable settings like these: "qa.env", "stg-env", "PROD_ENV".Running
Also I recommend using the "dotenv" module, it put all the ENV variables into the proccess object, pretty neat by the way.Uriiah
M
47

It depends on your operating system and your shell

On linux with the shell bash, you create environment variables like this(in the console):

export FOO=bar

For more information on environment variables on ubuntu (for example):

Environment variables on ubuntu

Megagamete answered 10/3, 2014 at 22:31 Comment(6)
Then see this answer: #136188Megagamete
And what about Windows? Could you please add here?Atlas
Ah, nevermind, looks like it's answered here: #9250330Atlas
in Linux bash are these values persisted? what if I just want to run it only while the terminal is open so as to not cause issues with other applications later?Tuppence
This worked perfectly for my need - for my npm install --save geo-ip which required an environment key=value setting for the install to work.Splenetic
And about Mac? I use shelljs which create a child processEpirus
K
35

Windows-users: beware! These commands are recommended for Unix. But on Windows they don't persist, they only set a variable in your current shell, and it'll be gone when you restart.

  • SET TEST="hello world"
  • $env:TEST = "hello world"

3 ways to set a persistent environment variable on Windows:

A) .env file in your project - The best method. As you can just copy that file to any computer and get the same config when running the project.

  1. Create an .env file in your project folder root with the content: TEST="hello world"

  2. Write some node code that will read that file. I suggest installing dotenv ( npm install dotenv --save) and then add require('dotenv').config(); during your node setup code.

  3. process.env.TEST is now usable in node

Env-files are a good way of keeping api-keys out of your codebase

B) Use Powershell - this will create a variable that will be accessible in other terminals. But it sucks as it'll be lost after you restart your computer.

[Environment]::SetEnvironmentVariable("TEST", "hello world", "User")

This method is widely recommended on Windows forums, people seem unaware it doesn't persist after a system restart....

C) Use the Windows GUI

Search for "Environment Variables" in the Start Menu Search or in the Control Panel, Select "Edit the system environment variables". A dialogue opens and you click the button "Environment Variables" at the bottom of the dialogue to open an edit-view where you can click the "New" button to add a new environment variable. Easy. And persists even after a restart. But not something you should use to config a specific codebase.

Kamakura answered 25/9, 2016 at 20:7 Comment(0)
M
24

Like ctrlplusb said, I recommend you to use the package dotenv, but another way to do this is creating a js file and requiring it on the first line of your app server.

env.js:

process.env.VAR1="foo"
process.env.VAR2="bar"

app.js:

require('./env') // env.js relative path.
console.log(process.env.VAR1) // foo
Mccluskey answered 14/9, 2018 at 17:51 Comment(2)
I get error saying Error: Cannot find module 'env'Gabbert
it should be require('./env')Gabbert
A
12

Step 1: Add your environment variables to their appropriate file. For example, your staging environment could be called .env.staging, which contains the environment variables USER_ID and USER_KEY, specific to your staging environment.

Step 2: In your package.json file, add the following:

"scripts": {
  "build": "sh -ac '. ./.env.${REACT_APP_ENV}; react-scripts build'",
  "build:staging": "REACT_APP_ENV=staging npm run build",
  "build:production": "REACT_APP_ENV=production npm run build",
  ...
}

then call it in your deploy script like this:

npm run build:staging

Super simple set up and works like a charm!

Source: https://medium.com/@tacomanator/environments-with-create-react-app-7b645312c09d

Ambulacrum answered 19/10, 2017 at 0:1 Comment(2)
do not work on windows.Sphenoid
@Sphenoid I agree, never use Windows for production servers for node.Ambulacrum
C
7

Make your life easier with dotenv-webpack. Simply install it npm install dotenv-webpack --save-dev, then create an .env file in your application's root (remember to add this to .gitignore before you git push). Open this file, and set some environmental variables there, like for example:

ENV_VAR_1=1234
ENV_VAR_2=abcd
ENV_VAR_3=1234abcd

Now, in your webpack config add:

const Dotenv = require('dotenv-webpack');
const webpackConfig = {
  node: { global: true, fs: 'empty' }, // Fix: "Uncaught ReferenceError: global is not defined", and "Can't resolve 'fs'".
  output: {
    libraryTarget: 'umd' // Fix: "Uncaught ReferenceError: exports is not defined".
  },
  plugins: [new Dotenv()]
};
module.exports = webpackConfig; // Export all custom Webpack configs.

Only const Dotenv = require('dotenv-webpack');, plugins: [new Dotenv()], and of course module.exports = webpackConfig; // Export all custom Webpack configs. are required. However, in some scenarios you might get some errors. For these you have the solution as well implying how you can fix certain error.

Now, wherever you want you can simply use process.env.ENV_VAR_1, process.env.ENV_VAR_2, process.env.ENV_VAR_3 in your application.

Condor answered 15/8, 2019 at 11:46 Comment(0)
V
5

If you are using a mac/linux and you want to retrieve local parameters to the machine you're using, this is what you'll do:

  1. In terminal run nano ~/.zshrc
  2. add a line like: export MY_VAR=var
  3. save & run source ~/.zshrc
  4. in node use like: console.log(process.env.MY_VAR);

Replace .zshrc with .bashrc or your config file, depending on what shell you're using (and replace nano with your preferred editor).

Varletry answered 5/9, 2019 at 15:13 Comment(1)
This is exactly what I want. ThanksRheum
B
4

For windows users this Stack Overflow question and top answer is quite useful on how to set environement variables via the command line

How can i set NODE_ENV=production in Windows?

Blastocoel answered 15/9, 2014 at 20:6 Comment(0)
H
4

Came across a nice tool for doing this.

node-env-file

Parses and loads environment files (containing ENV variable exports) into Node.js environment, i.e. process.env - Uses this style:

.env

# some env variables

FOO=foo1
BAR=bar1
BAZ=1
QUX=
# QUUX=
Huneycutt answered 13/6, 2015 at 9:44 Comment(0)
D
3

As expansion of @ctrlplusb answer,
I would suggest you to also take a look to the env-dot-prop package.

It allows you to set/get properties from process.env using a dot-path.

Let's assume that your process.env contains the following:

process.env = {
  FOO_BAR: 'baz'
  'FOO_🦄': '42'
}

Then you can manipulate the environment variables like that:

const envDotProp = require('env-dot-prop');

console.log(process.env);
//=> {FOO_BAR: 'baz', 'FOO_🦄': '42'}

envDotProp.get('foo');
//=> {bar: 'baz', '🦄': '42'}

envDotProp.get('foo.🦄');
//=> '42'

envDotProp.get('foo.🦄', {parse: true});
//=> 42

envDotProp.set('baz.foo', 'bar');
envDotProp.get('', {parse: true});
//=> {foo: {bar: 'baz', '🦄': 42}, baz: {foo: 'bar'}}

console.log(process.env);
//=> {FOO_BAR: 'baz', 'FOO_🦄': '42', BAZ_FOO: 'bar'}

envDotProp.delete('foo');
envDotProp.get('');
//=> {baz: {foo: 'bar'}}

console.log(process.env);
//=> {BAZ_FOO: 'bar'}

This helps you to parse the environment variables and use them as a config object in your app.
It also helps you implement a 12-factor configuration.

Deference answered 25/7, 2017 at 15:30 Comment(0)
D
3

A very good way of doing environment variables I have successfully used is below:

A. Have different config files:

  1. dev.js // this has all environment variables for development only
    The file contains:

    module.exports = {
     ENV: 'dev',
     someEnvKey1 : 'some DEV Value1',
     someEnvKey2 : 'some DEV Value2'
    };
    
  2. stage.js // this has all environment variables for development only

    ..
    
  3. qa.js // this has all environment variables for qa testing only
    The file contains:

    module.exports = {
     ENV: 'dev',
     someEnvKey1 : 'some QA Value1',
     someEnvKey2 : 'some QA Value2'
    };
    

NOTE: the values are changing with the environment, mostly, but keys remain same.

  1. you can have more

  2. z__prod.js // this has all environment variables for production/live only
    NOTE: This file is never bundled for deployment

  3. Put all these config files in /config/ folder

    <projectRoot>/config/dev.js
    <projectRoot>/config/qa.js
    <projectRoot>/config/z__prod.js
    <projectRoot>/setenv.js
    <projectRoot>/setenv.bat
    <projectRoot>/setenv.sh
    

NOTE: The name of prod is different than others, as it would not be used by all.

B. Set the OS/ Lambda/ AzureFunction/ GoogleCloudFunction environment variables from config file

Now ideally, these config variables in file, should go as OS environment variables (or, LAMBDA function variables, or, Azure function variables, Google Cloud Functions, etc.)

so, we write automation in Windows OS (or other)

  1. Assume we write 'setenv' bat file, which takes one argument that is environment that we want to set

  2. Now run "setenv dev"

a) This takes the input from the passed argument variable ('dev' for now)
b) read the corresponding file ('config\dev.js')
c) sets the environment variables in Windows OS (or other)

For example,

The setenv.bat contents might be:

    node setenv.js

The setenv.js contents might be:

    // import "process.env.ENV".js file (dev.js example)
    // loop the imported file contents
    //     set the environment variables in Windows OS (or, Lambda, etc.)

That's all, your environment is ready for use.

When you do 'setenv qa', all qa environment variables will be ready for use from qa.js, and ready for use by same program (which always asks for process.env.someEnvKey1, but the value it gets is qa one).

Hope that helps.

Dallon answered 18/8, 2017 at 3:54 Comment(0)
R
2

Pretty much like some others answers but without any lib nor (bash) export.

I have some encrypted variables then I need to generate them on the fly.

The magic happens with set -a && ... && set +a which can be some content or a file.

#!/bin/sh

set -a    
SOMEVAR_A="abcd"
SOMEVAR_B="efgh"
SOMEVAR_C=123456
set +a

# or
set -a && . ./file && set +a

I have a docker-entrypoint.sh with:

#!/bin/sh

node app/config/set-environment.js

ENVFILE=/tmp/.env

if [[ ! -f "$ENVFILE" ]] ; then
    echo "File $ENVFILE is not there, aborting."
    exit
fi

# here is where things happen
set -a && . $ENVFILE && set +a

if [ "${NODE_ENV}" = "development" ]; then
  npx nodemon app/server.js
else
  node app/server.js
fi

exec "$@"

While set-environment.js generates a (tmp) .env file

Rhigolene answered 18/7, 2022 at 18:30 Comment(0)
S
1

Use cross-env. It will save you a lot of headache

npm i -S cross-env

cross-env PARAM=value node ./index.js

That's usually good for non-credentials. For things like credentials and keys it's better not to store hardcoded user id and password but use .env file which is not in repo and dotenv

Shopping answered 15/9, 2021 at 11:23 Comment(0)
G
0

I was getting undefined after setting a system env var. When I put APP_VERSION in the User env var, then I can display the value from node via process.env.APP_VERSION

Gitagitel answered 2/6, 2016 at 5:39 Comment(0)
A
0

in case you're using visual studio code debugging feature, you can add "envFile": "${workspaceRoot}/.env" to launch configuration. This way you don't have to use dotenv.

{
        "cwd": "${workspaceRoot}",
        "command": "npm start",
        "name": "Run be",
        "request": "launch",
        "type": "node-terminal",
        "envFile": "${workspaceRoot}/.env"
},
Amelioration answered 30/4, 2021 at 9:23 Comment(0)
C
0

Make a file called local-env and populate it with variables

PORT=80
DB_NAME=foo
SOME_URL=example.com

Now run node thusly:

source ./local_env ; node index.js
Claman answered 27/8, 2022 at 6:34 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.