Skip to content
๐Ÿ–ฅ๏ธEnvironments & Secrets

Environments & Secrets

beginner Python 12 minenvironmentsenvironment variablessecrets
What you'll learn
  • environments
  • environment variables
  • secrets
  • .env
  • 12-factor
  • .gitignore

Environments & Secrets - Config Without Catastrophe ๐Ÿ”

A true story (it happens constantly). A developer accidentally committed their AWS key to a public GitHub repo. Bots scrape GitHub for keys every minute - within 9 minutes theirs was found and used to spin up servers mining crypto. The bill: tens of thousands of dollars. This lesson is how you never become that story.

๐Ÿง  The mental model: rehearsal โ†’ dress rehearsal โ†’ opening night

Your code runs in several environments - same script, very different stakes:

EnvironmentLike...Talks to
developmentrehearsing in your bedroomfake / local data
stagingdress rehearsal on the real stagea copy of production
productionopening night, live audiencethe real database & users

The golden rule: the exact same build runs everywhere. Only the configuration changes.

Config lives in the environment, not the code (the "12-Factor" rule)

How does the same build know which database to use? Environment variables - values set outside your code, per environment:

Python
import os
DATABASE_URL = os.environ["DATABASE_URL"]    # set per-environment, never hardcoded
ENV = os.environ.get("ENV", "development")    # .get() with a safe default

Locally you keep them in a .env file, which a library such as python-dotenv loads into the environment when the app starts; in production your platform (Vercel, AWSโ€ฆ) injects them.

The secret rules (memorise these)

  1. Never put keys, passwords, or tokens in source code or Git.
  2. Add .env to .gitignore so it is never committed.
  3. If a secret leaks, rotate it immediately - deleting the commit is NOT enough, because Git keeps history.
bash
# .gitignore
.env
*.key

The #1 production outage you'll cause

A required secret that is present but empty (""). The app boots, then explodes three hours into the night run. Validate config at startup and fail loudly - an empty string is "missing".

๐Ÿ”ง Try it for real

bash
# create local config, and make sure it is never committed
echo 'API_KEY=test123' > .env
echo '.env' >> .gitignore
# the operating system never reads .env, so this prints NOT SET
python3 -c "import os; print(os.environ.get('API_KEY', 'NOT SET'))"
# a variable set for one command does reach it: this prints test123
API_KEY=test123 python3 -c "import os; print(os.environ.get('API_KEY', 'NOT SET'))"

Your Task

Read a config dict, detect the environment, and validate that all required secrets are present - treating an empty value as missing (the classic outage).