Environment Variables & Secrets: .env, Twelve-Factor, and Safe Defaults

Separate config from code, ship .env.example, wire CI secrets, and never commit API keys—plus what to do if you leak one.

Security & secrets Intermediate 6 min read

·

Environment variables separate configuration from code so the same container or binary can run in dev, staging, and prod with different secrets and endpoints. You use .env locally for convenience but avoid committing it because anyone with repo access would inherit production credentials.

Use Git carefully—see Git basics.

What belongs in environment variables?

  • Database URLs and API keys
  • Feature flags and environment names (APP_ENV=prod)
  • Ports and hostnames that differ per machine

Why not hard-code these: Rebuilds would be required for every secret rotation; leaks embed secrets in image layers and Git history.

.env in local development

Why .env.example: New developers copy it to .env and fill real values—documentation stays close to the code without exposing secrets.

Tools like Symfony, Laravel, Node’s dotenv, and Docker Compose read a .env file. Commit a .env.example (no secrets) listing required keys with dummy values.

Production and CI

Why inject at runtime: Orchestrators and PaaS platforms can rotate secrets without redeploying app code; audit logs show which service account read which secret.

Inject secrets from your host (Kubernetes secrets, systemd EnvironmentFile, PaaS config vars, or CI encrypted variables). Rotate keys when people leave the team or after any leak.

If a secret hit Git history

Why assume compromise: Bots scan public GitHub in seconds; private repos still leak via forks and backups. Rotation is faster than proving non-disclosure.

Revoke and rotate the credential, then remove or rewrite history if policy requires—prevention beats cleanup.

Docker Compose

Why Compose reads .env: Variable substitution in YAML keeps passwords out of the compose file itself; the compose file can stay in Git while .env stays local.

See Docker Compose tutorial.

Frequently asked questions

Are .env files encrypted?

Not by default—treat them as plaintext secrets on disk. Restrict file permissions and exclude from archives you share.

Should secrets live in a vault?

For production at scale, yes—use a secret manager (cloud or self-hosted) with audit logs and rotation.

What about dotenv in the browser?

Never expose server secrets to frontend bundles; only NEXT_PUBLIC_-style vars that are intentionally public belong in client code.

12-factor and Docker?

Containers should receive config at runtime (env, mounted files, orchestrator secrets)—not bake secrets into image layers.