Environment Variable
An environment variable is a named value stored in a process's environment that child processes inherit. Environment variables configure application behaviour without hardcoding values. They are the standard method for passing configuration, secrets, and runtime settings to processes.
Understanding Environment Variables
What Is an Environment Variable in Simple Terms
Every running process on Linux has a set of key-value pairs called its environment. These are not part of the code — they are external configuration that the process can read at runtime. DATABASE_URL, NODE_ENV, PORT, AWS_REGION — all of these are typically environment variables.
This is why the same Docker container can run in development (NODE_ENV=development) and production (NODE_ENV=production) without any code changes — only the environment changes.
How It Works
+------------------------------------------+| Parent process environment || NODE_ENV=production || PORT=4000 || DB_HOST=10.0.2.100 |+------------------------------------------+ | fork() + exec() | v+------------------------------------------+| Child process inherits all variables || NODE_ENV=production <- inherited || PORT=4000 <- inherited || DB_HOST=10.0.2.100 <- inherited |+------------------------------------------+Practical Commands
## View all environment variablesenvprintenv ## View a specific variableecho $NODE_ENVprintenv NODE_ENV ## Set a shell variable (local to current shell, NOT inherited)MY_VAR=helloecho $MY_VAR ## worksbash -c 'echo $MY_VAR' ## empty -- not exported ## Export a variable (becomes environment variable, inherited by children)export MY_VAR=hellobash -c 'echo $MY_VAR' ## hello -- now inherited ## Set and export in one lineexport NODE_ENV=productionexport PORT=4000export DB_HOST=10.0.2.100 ## Unset a variableunset MY_VAR ## Set variable for ONE command only (does not persist)NODE_ENV=staging node server.js## NODE_ENV is staging only for this commandecho $NODE_ENV ## whatever it was before ## Load from a .env fileexport $(cat .env | grep -v '^#' | xargs) ## Check in a running processcat /proc/1234/environ | tr '\0' '\n' | grep NODE_ENV ## Variable expansion modifiersecho ${MY_VAR:-default} ## use default if MY_VAR unset or emptyecho ${MY_VAR:=default} ## assign default if MY_VAR unsetecho ${MY_VAR:?"error"} ## exit with error if MY_VAR unsetTroubleshooting
| Symptom | Command | What to Check |
|---|---|---|
| App ignores env var | printenv VAR_NAME |
Variable not exported |
| Var set but child does not see | export VARNAME |
Must export, not just assign |
| Secret in env visible to others | cat /proc/PID/environ |
Anyone with access can read it |
SecurityEnvironment variables are visible to any user who can read
/proc/PID/environfor that process. Never store long-lived secrets like private keys in environment variables for long-running production processes. Use a secrets manager (Vault, AWS Secrets Manager) and inject secrets as files instead.
Remember
exportis what makes a shell variable into an environment variable. Withoutexport, the variable exists only in the current shell and is not passed to any child processes, scripts, or commands you run.
Frequently Asked Questions
Why are environment variables preferred over config files for secrets and runtime settings?
Environment variables live in process memory rather than on disk, so they don't get accidentally committed to version control the way a checked-in config file might, and they're natively supported across virtually every language and container runtime without needing a parser. They also let the same built artifact (Docker image, binary) behave differently across dev, staging, and production purely by varying what's injected at startup — no rebuild required, which is central to twelve-factor app design.
What's a common mistake when passing secrets via environment variables in containers?
Environment variables are visible to any process that can read /proc/[pid]/environ, show up in crash dumps and error logs, and are often echoed unintentionally by CI systems or `docker inspect`. For genuinely sensitive values, a mounted secrets file or a dedicated secrets manager (Vault, AWS Secrets Manager) with restricted read access is safer than an env var, even though env vars remain fine for non-sensitive config like log level or feature flags.