{# canonical_base is the OWNING tenant's origin: all 16 Peasy domains serve the same catalogue, so a page rendered by a non-owner points its canonical at the owner instead of competing with it. Falls back to this site for static/self-owned pages. #}
🍋
Menu
Best Practice Beginner 2 min read 361 words

Environment Variable Management: Security and Best Practices

Environment variables separate configuration from code, keeping secrets out of version control. Mismanaging them leads to leaked API keys, broken deployments, and configuration drift between environments.

Key Takeaways

  • Hardcoding configuration values — database URLs, API keys, feature flags — into source code creates three problems: secrets end up in version control (and Git history forever), the same code can't run in different environments without modification, and configuration changes require code deployments.
  • `.env` files store key-value pairs loaded at application startup:
  • Maintain separate configurations for each environment:
  • For small teams, 1Password or similar tools can store and sync `.env` files.
  • Using different variable names across environments (DB_HOST vs DATABASE_HOST) causes confusion.

Why Environment Variables Exist

Hardcoding configuration values — database URLs, API keys, feature flags — into source code creates three problems: secrets end up in version control (and Git history forever), the same code can't run in different environments without modification, and configuration changes require code deployments.

Environment variables solve all three by storing configuration outside the codebase, injected at runtime.

The .env File Pattern

Structure

.env files store key-value pairs loaded at application startup:

DATABASE_URL=postgres://user:pass@host:5432/dbname
DJANGO_SECRET_KEY=a-long-random-string-here
STRIPE_API_KEY=sk_live_...
DEBUG=false
ALLOWED_HOSTS=example.com,www.example.com

Critical Rule: Never Commit .env Files

Add .env and .env.prod to .gitignore immediately when starting a project. If a secret is committed even once, it exists in Git history forever — even after deleting the file. Leaked secrets should be rotated immediately, not just removed from the repository.

.env.example

Maintain a .env.example file (committed to Git) that lists all required variables with placeholder values. This documents what configuration a new developer needs without exposing actual secrets:

DATABASE_URL=postgres://user:password@localhost:5432/myapp
DJANGO_SECRET_KEY=change-me-to-a-random-string
STRIPE_API_KEY=sk_test_...

Environment Separation

Per-Environment Configuration

Maintain separate configurations for each environment:

Variable Development Staging Production
DEBUG true false false
DATABASE_URL localhost staging-rds production-rds
LOG_LEVEL DEBUG INFO WARNING
API keys Test keys Test keys Live keys

Never use production secrets in development. Most third-party services provide separate test/sandbox keys for this reason.

Secret Management at Scale

Password Managers

For small teams, 1Password or similar tools can store and sync .env files. A sync-secrets command pulls the latest values from the password manager and writes them to the local .env file.

Cloud Secret Managers

For larger deployments, use AWS Secrets Manager, Google Secret Manager, or HashiCorp Vault. These provide access control, audit logging, automatic rotation, and versioning. Applications fetch secrets at startup rather than reading from files.

Common Mistakes

Using different variable names across environments (DB_HOST vs DATABASE_HOST) causes confusion. Default values in code that silently override missing environment variables can mask configuration errors. Always fail loudly if a required environment variable is missing.