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 appREQUIRED_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).
Full-stack dev, designer, entrepreneur, open-source lover. Building DMNO - the best way to configure, run, and deploy your whole stack. Run `npx dmno init` to get started!
Nice article. I think you might like a new tool we just released - varlock.dev
Instead of a .env.example you create a .env.schema which will never get out of sync. It uses decorator comments to add extra metadata that lets us add validation, type safety, and extra protections for your sensitive config.
Would love to hear what you think - hop in our discord and say hello!
For further actions, you may consider blocking this person and/or reporting abuse
We're a place where coders share, stay up-to-date and grow their careers.
Top comments (1)
Nice article. I think you might like a new tool we just released - varlock.dev
Instead of a
.env.example
you create a.env.schema
which will never get out of sync. It uses decorator comments to add extra metadata that lets us add validation, type safety, and extra protections for your sensitive config.Would love to hear what you think - hop in our discord and say hello!