KAHIBARO
Discord Login Register

3.4. Environment Variables

Why Environment Variables Matter

Every backend application needs configuration values, for example:

You must not hard‑code these values into your source code. Instead, you read them from environment variables.

Environment variables keep secrets out of code, allow different settings per environment (development, staging, production), and make your app easier to deploy on any machine or container.

Rule: Never hard‑code secrets like passwords, API keys, or tokens in source code. Use environment variables instead.

In this chapter you will learn what environment variables are, how to set and read them on Linux, macOS, and Windows, and how they connect to backend development and tools like Python and Docker.


What Are Environment Variables?

An environment is the context in which a process (a running program) executes. This environment includes:

Environment variables are simple KEY=VALUE pairs that are attached to a process and inherited by child processes.

Examples:

When you start your backend server from a shell, the server process sees the environment variables that existed in that shell at the moment of starting.

You can think of environment variables as a global dictionary of strings that your program can read.


Built‑in Environment Variables You Will See Often

Most operating systems define some common variables automatically.

Typical examples:

VariableMeaning (typical)Example value
HOMEUser’s home directory (Linux/macOS)/home/alice
USERCurrent usernamealice
PATHList of directories searched for programs/usr/local/bin:/usr/bin:/bin
SHELLUser’s default shell (Linux/macOS)/bin/bash
PWDCurrent working directory/home/alice/projects/app
TEMPTemporary files directory (Windows)C:\Users\Alice\AppData\Local\Temp
USERNAMECurrent username (Windows)Alice

Backend apps rarely change these built‑ins, but they always rely on PATH and they will add many custom variables for configuration.


Viewing Environment Variables

You should know how to inspect environment variables from the command line.

On Linux and macOS

Open a terminal.

bash
printenv

or

bash
env

You will see lines like:

text
SHELL=/bin/bash
USER=alice
HOME=/home/alice
PATH=/usr/local/bin:/usr/bin:/bin
bash
echo "$PATH"

Example output:

text
/usr/local/bin:/usr/bin:/bin

Note the quotes around $PATH. They are often optional, but they are a good habit.

On Windows (Command Prompt)

Open Command Prompt (cmd.exe).

cmd
set

You will see:

text
ALLUSERSPROFILE=C:\ProgramData
USERNAME=Alice
PATH=C:\Windows\System32;C:\Windows;...
cmd
echo %PATH%

On Windows (PowerShell)

Open PowerShell.

powershell
Get-ChildItem Env:
powershell
$Env:PATH

Setting Environment Variables Temporarily in a Shell

You often want to set a variable only for your current terminal session, for example while developing locally.

Once you close that terminal, the value disappears.

Linux and macOS: `export`

In a Bash or Zsh shell:

bash
export APP_ENV=development
export DATABASE_URL="postgresql://user:pass@localhost:5432/appdb"

You can verify:

bash
echo "$APP_ENV"

If you close the terminal window and open a new one, APP_ENV will not exist anymore unless you add it to a configuration file like ~/.bashrc or ~/.zshrc.

Only for a Single Command

You can also define an environment variable just for one command:

bash
APP_ENV=production python main.py

In this example:

You will see this pattern very often when running backend services:

bash
PORT=8000 DEBUG=false uvicorn app.main:app

Windows (Command Prompt): `set`

In cmd.exe:

cmd
set APP_ENV=development
set DATABASE_URL=postgresql://user:pass@localhost:5432/appdb

Check the value:

cmd
echo %APP_ENV%

These values last only until you close that Command Prompt window.

To set a variable only for one command in cmd.exe you typically have to write a batch script. Command Prompt does not have a simple inline syntax like Bash.

Windows (PowerShell): `$Env:`

In PowerShell:

powershell
$Env:APP_ENV = "development"
$Env:DATABASE_URL = "postgresql://user:pass@localhost:5432/appdb"

Check the value:

powershell
$Env:APP_ENV

This lasts for the duration of that PowerShell session only.


Setting Environment Variables Permanently

To avoid setting the same variables manually every time, you can define them permanently.

You will commonly do this for:

For application secrets, you usually prefer dedicated configuration files or secret managers because permanent system‑wide environment variables can leak more easily.

Linux and macOS: Shell Configuration Files

You can add export lines to shell startup files such as:

Example for Bash:

  1. Open the file:
bash
   nano ~/.bashrc
  1. Add lines at the end:
bash
   export APP_ENV=development
   export EDITOR=vim
  1. Reload the file in the current terminal:
bash
   source ~/.bashrc

Now, every new terminal will have APP_ENV set.

Rule: Do not commit your shell config files if they contain secrets. Keep API keys, database passwords, and similar values out of version control.

Windows: System Environment Variables

On Windows you can define environment variables permanently through the graphical interface.

Steps (Windows 10/11):

  1. Press Win key, search for "Environment Variables"
  2. Choose Edit the system environment variables
  3. In the dialog, click Environment Variables...
  4. Under User variables click New... to define APP_ENV, DATABASE_URL, and similar settings
  5. Click OK to save

These will be available to new Command Prompt or PowerShell sessions.

You can also use PowerShell for user‑scoped variables, for example:

powershell
[Environment]::SetEnvironmentVariable("APP_ENV", "development", "User")

New PowerShell or Command Prompt windows will see the new variable.


Environment Variables and the PATH

PATH is a special environment variable that controls where your shell looks for programs.

PATH is a list of directories separated by:

Example on Linux:

text
/usr/local/bin:/usr/bin:/bin

When you type:

bash
python

the shell searches through each directory listed in PATH for a program named python.

If you install a new tool (for example pip, uvicorn, or docker) and the command is “not found”, often the folder with that executable is not in your PATH.

Example: Add a directory to PATH (Linux/macOS)

Suppose Python tools are in /home/alice/.local/bin. You can add it:

bash
export PATH="$HOME/.local/bin:$PATH"

Or permanently in ~/.bashrc:

bash
echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.bashrc
source ~/.bashrc

Example: Add to PATH (Windows, PowerShell, current session)

powershell
$Env:PATH = "C:\Tools\bin;" + $Env:PATH

For permanent PATH changes use the Windows environment dialog or:

powershell
[Environment]::SetEnvironmentVariable(
    "Path",
    $Env:Path + ";C:\Tools\bin",
    "User"
)

Be careful with PATH. If you accidentally delete its existing value, many commands will stop working.


Using Environment Variables in Backend Applications

In backend development you rarely care about HOME or USER, but you always care about custom variables such as:

VariableTypical purpose
APP_ENVApplication environment (development, staging)
PORTPort the server listens on (8000, 80, 443)
DATABASE_URLFull database connection string
REDIS_URLRedis connection string
SECRET_KEYSecret key used for signing cookies or tokens
LOG_LEVELLog verbosity level (info, debug, error)

These values let you use the same codebase with different configurations.

Example scenario:

text
  APP_ENV=development
  DATABASE_URL=postgresql://dev_user:dev_pass@localhost:5432/appdb
text
  APP_ENV=production
  DATABASE_URL=postgresql://prod_user:prod_pass@db-server:5432/appdb

The code reads DATABASE_URL at runtime. It does not need to know where it is running.


Example: Reading Environment Variables in Python

You will learn this more deeply in the Python chapters. For now, here is a basic pattern.

python
import os
# Read environment variable, or use a default if not set
app_env = os.getenv("APP_ENV", "development")
# Raises KeyError if SECRET_KEY is not set
secret_key = os.environ["SECRET_KEY"]

Difference between os.getenv and os.environ[...]:

MethodWhen variable is missing
os.getenv("KEY")Returns None (or default value)
os.environ["KEY"]Raises KeyError

You can combine environment variables with default values:

python
port = int(os.getenv("PORT", "8000"))
debug = os.getenv("APP_ENV", "development") == "development"

Later, when you run the app in your shell:

bash
export APP_ENV=production
export PORT=8080
python main.py

The app will use these values.


Example: Simple Configuration Pattern

A common backend pattern is to centralize configuration in one place.

python
import os
class Settings:
    def __init__(self):
        self.env = os.getenv("APP_ENV", "development")
        self.database_url = os.getenv("DATABASE_URL")
        self.secret_key = os.getenv("SECRET_KEY")
        self.port = int(os.getenv("PORT", "8000"))
        # Simple validation
        if not self.database_url:
            raise RuntimeError("DATABASE_URL must be set")
        if not self.secret_key:
            raise RuntimeError("SECRET_KEY must be set")
settings = Settings()

Then other parts of the app import settings:

python
from config import settings
print(settings.database_url)

This design keeps all environment‑based configuration in one place.


Using `.env` Files (Local Development)

Typing export commands every time can be annoying. A common solution in development is to create a .env file and load it automatically.

A .env file is a simple text file with KEY=VALUE lines:

Example .env:

text
APP_ENV=development
DATABASE_URL=postgresql://dev_user:dev_pass@localhost:5432/appdb
SECRET_KEY=dev-secret-key
PORT=8000

You can then use tools or libraries to load this file into your environment.

Common approaches:

bash
  set -a
  source .env
  set +a

This exports all variables defined in .env into the current shell.

python
  from dotenv import load_dotenv
  load_dotenv()  # loads .env into environment
  import os
  db_url = os.getenv("DATABASE_URL")

Rule: Never commit .env files with real secrets to a public repository.
If you need to share variable names, create an example file like .env.example that contains placeholder values.


Common Pitfalls and How to Avoid Them

Environment variables look simple, but beginners hit the same issues repeatedly. Here are the most common cases.

1. Variable Only Exists in One Shell

You start your app from a different terminal, and the variable is missing.

Example:

Terminal 1:

bash
export SECRET_KEY=abc123

Terminal 2:

bash
python main.py

SECRET_KEY is not set in Terminal 2, so your app fails.

Fix: Either export the variable in every shell where you run the app or add it to a startup file like ~/.bashrc, or use a .env file and load it each time.

2. Value Not Visible Because of Wrong Command

On Windows:

cmd
set APP_ENV=development

This works only in Command Prompt (cmd.exe). If you open PowerShell and run:

powershell
$Env:APP_ENV

you will not see it because PowerShell has its own environment session.

Fix: Use the right syntax for the shell you use, or define permanent user variables with the system dialog.

3. PATH Overwritten Instead of Extended

You want to add /opt/mytool/bin to PATH but accidentally do:

bash
export PATH="/opt/mytool/bin"

Now basic commands like ls or python may stop working.

Fix: Append or prepend to the existing PATH:

bash
export PATH="/opt/mytool/bin:$PATH"    # Linux/macOS

or

powershell
$Env:PATH = "C:\MyTool\bin;" + $Env:PATH   # Windows PowerShell

4. Spaces and Special Characters

Values with spaces or symbols can be parsed incorrectly if not quoted.

Example:

bash
export SECRET_KEY=my secret key

The shell reads my as the value and ignores the rest.

Fix: Quote values containing spaces or special characters:

bash
export SECRET_KEY="my secret key"

5. Case Sensitivity

On Linux and macOS, variable names are case sensitive.

On Windows they are typically case insensitive.

To avoid confusion, always use uppercase variable names with underscores, for example APP_ENV, DATABASE_URL.


Environment Variables in Docker and Cloud

You will use environment variables heavily when you start deploying with Docker and cloud platforms.

Examples you will see later:

bash
  docker run -e APP_ENV=production -e PORT=8000 my-backend-image
yaml
  services:
    web:
      image: my-backend-image
      environment:
        - APP_ENV=production
        - DATABASE_URL=${DATABASE_URL}
bash
  heroku config:set APP_ENV=production SECRET_KEY=super-secret

In all these cases, the pattern stays the same:

  1. Set variable in the environment
  2. Start the application process
  3. Application reads the variables at runtime

Practical Exercises

To solidify your understanding, try these short tasks on your machine.

Exercise 1: Temporary Variable

  1. Open a terminal (Linux/macOS) or PowerShell (Windows).
  2. Set a variable APP_ENV to development.
  3. Print its value.
  4. Close the terminal and open a new one.
  5. Try to print APP_ENV again, observe the result.

Exercise 2: Simple Python Script

Create a file show_env.py:

python
import os
env = os.getenv("APP_ENV", "not set")
print(f"APP_ENV is: {env}")

Now:

  1. Run python show_env.py without setting APP_ENV.
  2. Set APP_ENV in your shell.
  3. Run the script again and see the difference.

Exercise 3: `.env` File

  1. Create a file .env:
text
   APP_ENV=development
   SECRET_KEY=test-secret
  1. In a Bash shell:
bash
   set -a
   source .env
   set +a
  1. Print variables:
bash
   echo "$APP_ENV"
   echo "$SECRET_KEY"

You will later integrate similar patterns into Python backend frameworks like FastAPI.


Summary

Understanding environment variables is a crucial step toward writing configurable, secure, and portable backend applications.

Views: 6

Comments

Please login to add a comment.

Don't have an account? Register now!