patternModeratepending
Environment variable management patterns
Viewed 0 times
env varsdotenvconfigurationsecretstwelve-factorenvironment
Problem
Need to manage environment variables safely across development, staging, and production environments.
Solution
Layered environment variable management:
Rules:
.gitignore:
# .env (development defaults - committed to repo)
DATABASE_URL=postgres://localhost:5432/myapp_dev
REDIS_URL=redis://localhost:6379
LOG_LEVEL=debug
API_PORT=3000
# .env.local (personal overrides - gitignored)
DATABASE_URL=postgres://localhost:5432/myname_dev
# .env.test (test environment - committed)
DATABASE_URL=postgres://localhost:5432/myapp_test
LOG_LEVEL=error# Validate at startup
import os
REQUIRED = ['DATABASE_URL', 'SECRET_KEY']
OPTIONAL = {'LOG_LEVEL': 'info', 'API_PORT': '3000'}
def load_config():
missing = [v for v in REQUIRED if v not in os.environ]
if missing:
raise SystemExit(f'Missing env vars: {", ".join(missing)}')
return {
'database_url': os.environ['DATABASE_URL'],
'secret_key': os.environ['SECRET_KEY'],
'log_level': os.environ.get('LOG_LEVEL', OPTIONAL['LOG_LEVEL']),
'port': int(os.environ.get('API_PORT', OPTIONAL['API_PORT'])),
}Rules:
- Never commit
.env.localor production secrets - Use
.env.exampleas template (committed, no real values) - Production secrets go in: vault (HashiCorp), cloud secrets manager, CI/CD variables
- Validate ALL required env vars at startup, not first use
- Use typed config objects, not raw os.environ everywhere
.gitignore:
.env.local
.env.production
.env.*.localWhy
Environment variables are the standard way to configure applications across environments (12-factor app). But without validation and organization, they become a source of runtime errors.
Gotchas
- Docker doesn't load .env files by default - use --env-file or docker-compose env_file
- Boolean env vars are strings - 'false' is truthy in most languages!
Context
Application configuration across multiple environments
Revisions (0)
No revisions yet.