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; 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
echo 'API_KEY=test123' > .env      # create local config
echo '.env' >> .gitignore          # make sure it's never committed
python -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).