
As the name suggests, an environment variable shapes the environment you are working in. Once you set an environment variable and run a command or application, it can read the variable and act differently.
Why are they used?
- Configuration: They let you change how a program works without altering its code (e.g., setting PATH to tell the OS where to find programs).
- Security: They can store sensitive data (like API keys) separately from code.
- Convenience: Instead of hardcoding values, programs can read these variables dynamically.
Examples:
export GOPATH=$HOME/go
Variable should be defined in the same command:
API_KEY="API_SECRET_KEY" node main.js
What does export
do?
- KEY=VALUE
- This sets the
KEY
variable only for the current shell session. - The variable is not inherited by child processes (e.g., other scripts or programs you run from this shell).
- This is useful if you only need the variable temporarily in the current shell.
- export KEY=VALUE
- This sets the
KEY
variable and exports it to the environment of the current shell and all child processes. - Any program or script you run from this shell will have access to
KEY
. - This is the standard way to set environment variables like
GOPATH=$HOME/go
o that Go tools (go build
,go install
, etc.) can access it.
What is $PATH?
Consider I have built a go application that takes two numbers and multiply it. I name the output binary multiply
. I can run it like:
/home/seraj/multiplier/multiply 4 6
# 24
If I need to run this app I have to address its path whenever I want to run it. Alteratively I can set an $PATH
environment variable in my shell that tells my shell where to look for binaries. Once set, I can run the previous command like this. PATH
environment variable is a colon-separated list of directories the shell scans to locate executable files:
multiply 3 7
# 28
Other examples are when one needs to
pnpm global add http-server
go install github.com/air-verse/air@latest
To add go binaries to my PATH:
export GOPATH=$HOME/go
export PATH=$PATH:$GOPATH/bin
More Inspection on the PATH Variable
It’s a given when you can run binaries like ls
, cp
, grep
and etc. so the path to these binaries is already included in your shell’s PATH.
To confirm this fact:
which grep
# /usr/bin/grep
echo $PATH
# /home/seraj/.local/share/pnpm:/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/lib/jvm/default/bin:/usr/bin/site_perl:/usr/bin/vendor_perl:/usr/bin/core_perl
As you can see in the results this path /usr/bin
is also included.
How to set environment variables permanently?
Setting envs in different shells are different.
Bash:
To add env: add your env to ~/.bashrc
TO update PATH: update it in ~/.profile
Fish
To Add env:
set -x GOPATH $HOME/go
To update PATH:
fish_add_path $GOPATH/bin
Examples
Some simple real world examples:
GoLang
package main
import (
"fmt"
"os"
)
func main() {
fmt.Printf("We are running our app in %s mode.", os.Getenv("RUN_MODE"))
}
Run the app:
RUN_MODE=PRODUCTION go run main.go
# We are running our app in PRODUCTION mode.
Docker
docker run -e RUN_MODE=PRODUCTION app-image:tag
Docker Compose
services:
image: app-image:tag
environment:
- RUN_MODE=PRODUCTION
Docker compose itself reads from .env
as default for its own environment variables:
services:
image: app-image:tag
environment:
- RUN_MODE=PRODUCTION
- PASSWORD=${PASSWORD}
if you store a file beside your docker-compose
file with name .env
it will automatically reads it into the docker compose.
Example .env
:
PASSWORD="MY_SECRET_PASSWORD"