DevOps for Node.js Engineers: Linux Environment Variables (Env Vars)
These are variables for the entire system.
Here are some example:
These variables are set by the operating system but can be change by the user.
Display all environment variables
printenv # displays all env vars with their value
printenv | less
printenv <variable_name> # displays the value
printenv | grep <variable_name> # search for variables
Like variables in scripts, you reference them by preceding them with a $ sign
echo $USER
Application environment variables
You can create your own environment variables.
A common use case for setting your own env vars is passing credentials to a program. AS a Node developer, you know that you never should put credentials in the code (aka hardcoded credentials — very bad practice).
Every back-end programming language has a way to access environment variables (except JavaScript which used to be front-end specific which is no longer the case with Node.js).
Make applications more flexible
Environment variables in applications allow to make them more flexible by not hardcoding environment related and sensitive information (URLs, authentication credentials, tokens, etc.).
By doing so, you have a single app that can run on multiple systems just changing the values of the environment variables, not the code of the app itself.
Create environment variables
On Linux, to create environment variables:
export <VAR_NAME>=<value>
# notice the export command to differentiate from local variables (in scripts for examples)
A common convention is to give global variables upper serpent cased NAMED(WORD_WORD_WORD).
The variables created with export are tied to the current terminal session window. If you open a new terminal window / session, you won’t see the variables created in the other one.
Delete environment variables
unset <VAR_NAME>
Persist user environment variables
As explained before, exported variables are tied to the current terminal session. To create persistent environment variables — available to all terminal sessions of a user.
You need to modify your shell-specific configuration file. That file is located in the home directory of your user:
If it does not exist, you will need to create it.
For example, if your shell is Bash, you will have a .bashrc file in the user home directory. If it’s Zsh, it will be a .zshrc file.
Recommended by LinkedIn
Each user has its own shell configuration files all located in each user home directory. Again, these files are user-specific.
The variables set in that shell-specific configuration file (.<SHELL>rc) are loaded whenever you log into that shell. To put it simply, every time you log in, that file will be loaded. So basically, that file is loaded once.
To add permanent environment variables, edit (or create) the shell configuration file and add the following:
export <ENV_VAR>=<value>
In the end, that shell configuration file is pretty much a script that is run at each login. It is also called the startup script.
If you want to access the new env vars you just added to the shell configuration file without logging out and logging back in, run the following:
source ~/.<SHELL>rc
# examples
source ~/.bashrc
source ~/.zshrc
# the source command reloads the startup script
Persist system environment variables
Regarding permanent system environment variables, it is located in the file:
/etc/environment
In there, you will find only one environment variable called PATH. It's a list of directories to executable files separated by : (colon):
PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin"
Basically, whenever you execute a command the system looks at the paths in that variable to tell the shell which directories to search for the executable in response to the executed command.
Whenever you install programs, there executable binary file will (/ should) be installed in one of the directories in the PATH so that you can run them in the terminal. Otherwise, you will see a command not found error. The executable files (scripts and binaries) in these directories are available to the entire system, to all users.
Add a custom user global command
Ok, let’s apply what you just learned.
Let’s say you want to run a program that displays Welcome <USER> for your current user and make it a global command but only for that user.
# create a script named "welcome" in your user home directory
#!/bin/bash
echo "Welcome $USER"
# make it executable for all users
chmod a+x welcome
# add the path to the script to the PATH global variable
# in .bashrc
PATH=$PATH:$HOME
# no export needed at the beginning because PATH is already exported
# reload the startup script
source .bashrc
# your program is not globally available for your user
# move to another directory and try your new global command by entering its name
The trick here is to set the PATH variable in your user’s shell configuration file, that way other users won’t have access to that global script. Of course, to create a global command for all users, you would put it somewhere like /usr/local/bin which is already on the PATH.
Environment variables with Node.js
As you already familiar as a Node developer, you access environment variables like so:
process.env # object containing copy of all system env vars
Let’s try a little experiment:
# create a temporary environment variable, in a terminal:
export TOTO=toto
Now start a Node process by running the node command
# print the TOTO env var
process.env.TOTO # prints 'toto'
# modify the value of that variable
process.env.TOTO = 'titi'
Exit the Node process and print the value of the env var:
printenv TOTO # prints: toto
As you can see the Node process did not modify the environment var on the system, which is a good thing in terms of security. Think about it, that would be a MAJOR vulnerability that a Node process could modify environment variables, meaning if your process got compromised, the system would be compromised.
That said, it is possible to modify environment variables from Node by calling the operating system APIs from the Node process. Again, process.env is just a copy of system variables.
That’s it
See you in the next article.