Environment Variables: A Guide to Configuration Management

What Are Environment Variables?

Environment variables are key-value pairs injected at runtime to configure how applications behave without altering source code. They empower configuration flexibility across local development, CI/CD pipelines, containers, and cloud deployments.

Why Environment Variables?

Purpose Description
๐Ÿ” Security Secrets (e.g. API keys, DB creds) stay out of source code.
๐Ÿงฑ Separation of concerns Decouple config from application logic.
๐ŸŒ€ Environment switching Seamlessly change configs between dev, staging, production.
๐Ÿ›  Dynamic behaviour Enable feature toggles, flags, and runtime settings.

Who Needs to Manage Env Vars?

Role Usage Example
Developers Local setup via .env
DevOps Engineers Inject env vars in containers, CI/CD workflows
Sysadmins Set OS-level vars or orchestrate secrets
Security Teams Manage secret stores and access control

When Should You Use Env Vars?

Use them when:

  • Switching between dev/staging/prod configurations
  • Storing sensitive credentials
  • Managing external service URLs
  • Enabling/disabling feature flags

Avoid using env vars for static or non-sensitive content that won’t change between environments.

Common Mistakes

โŒ Mistake ๐Ÿ’ฅ Risk / Issue
Committing .env files Secrets leaked in public/private repos
Storing secrets in frontend code Exposes API keys and tokens
No .env.example Hard for others to set up project
Missing defaults or fallbacks App crashes without required variables
Overloaded .env Difficult to manage, prone to typo errors
Using env() in Laravel outside config Caches won’t work as expected after deployment
Missing variable validation on boot Harder to debug issues due to missing context

Pros and Cons

โœ… Pros โŒ Cons
Simplifies configuration across environments Flat structureโ€”hard to organise without convention
Keeps secrets out of source code Prone to accidental exposure if misused
Integrates seamlessly with CI/CD and containers Lacks validation/type safety without additional tools
Enables dynamic runtime behaviour Debugging missing vars can be challenging

Best Practices by Context

Development

Practice Recommendation
Use .env and .env.local For personal overrides
Include .env.example With placeholders only
.env in .gitignore Always
Use dotenv loaders E.g. vlucas/phpdotenv, dotenv, etc.

Production

Practice Recommendation
Use secrets manager or CI/CD env injection Never rely on .env in production
Avoid baking secrets into Docker images Pass them at runtime instead
Inject through Kubernetes, Docker, etc. Maintain clean separation

Containers (Docker, Kubernetes)

Context Strategy
Docker Use --env, --env-file, or docker-compose.yml
Kubernetes Use ConfigMap (non-sensitive) and Secret (sensitive), mount as env or files

Do’s and โŒ Don’ts

โœ… Do โŒ Donโ€™t
Use .env.example Share .env with real values
Validate required envs at app boot Assume presenceโ€”use null fallbacks without warning
Document env usage Leave other developers guessing
Store secrets securely Hardcode them or expose in front-end
Use consistent naming (APP_, DB_, etc.) Use vague or conflicting keys

Framework-Specific Tips

โš™ Laravel

๐Ÿ”น Tip ๐Ÿ› ๏ธ How to Use
Use env() ONLY in config files Access with config('app.name'), not env()
Publish .env.example To onboard teams easily
Use config caching in production Run php artisan config:cache

โš™ Node.js (Express, NestJS)

๐Ÿ”น Tip ๐Ÿ› ๏ธ How to Use
Use dotenv to load .env require('dotenv').config()
Validate using packages like envalid For type safety and default values
Never expose secrets in React/Vue apps Use REACT_APP_* only for non-sensitive configs

โš™ Python (Django, FastAPI)

๐Ÿ”น Tip ๐Ÿ› ๏ธ How to Use
Use python-dotenv or os.environ.get() Load .env into environment
Leverage pydantic in FastAPI Define env schema via BaseSettings
Use decouple for Django projects Clean separation of code and config

โš™ Go

๐Ÿ”น Tip ๐Ÿ› ๏ธ How to Use
Use os.Getenv("KEY") Native approach
Consider packages like godotenv, viper For dotenv support and defaults
Avoid panic on missing keys Provide fallbacks or error out clearly

โš™ Java (Spring Boot)

๐Ÿ”น Tip ๐Ÿ› ๏ธ How to Use
Use application.properties with env vars ${ENV_VAR:default}
Prefer @Value or @ConfigurationProperties For injection and typing
Use secrets or ConfigMap in Kubernetes Spring supports externalised config out-of-box

โš™ Others (Ruby on Rails, .NET, etc.)

Framework Tip
Ruby on Rails Use dotenv-rails, Figaro, or Rails.application.credentials
.NET Core Use IConfiguration to bind from environment or secrets

๐Ÿงช Suggested Validation Strategy (General)

# Example shell script to check required envs before starting app
REQUIRED_VARS=("DB_HOST" "DB_USER" "DB_PASS" "APP_KEY")
for var in "${REQUIRED_VARS[@]}"
do
  if [[ -z "${!var}" ]]; then
    echo "โŒ Missing required env variable: $var"
    exit 1
  fi
done

Or, use programmatic validation (e.g., pydantic, envalid, custom boot checkers).

๐Ÿ“Œ Final Notes for Teams

  • Onboarding: Share .env.example, keep instructions up-to-date
  • Security: Rotate secrets, use proper access control
  • Monitoring: Alert on missing/misconfigured env vars
  • CI/CD: Never echo secrets in build logs

Photo by Bernd ๐Ÿ“ท Dittrich on Unsplash

Similar Posts