Environment & secrets

Golden rules

  • .env.local and similar files belong in .gitignore. Commit only .env.example with placeholder values.
  • Prefix public browser vars with NEXT_PUBLIC_ only when unavoidable; prefer server-side config for secrets.
  • Use GitHub Environments (Staging / Production) so CI injects different secrets per branch without mixing prod DB into staging builds.

Layers

Local development

Minimal .env: database URL, auth secret, maybe Stripe test keys. Use Stripe CLI for webhooks.

Staging (e.g. develop branch)

Staging DB, test Stripe mode or separate test products, Resend sandbox or domain-restricted sending.

Production

Live keys, live webhook endpoints, monitored Resend domain, Firebase production project for push.

Example shape (landing / checkout slice)

For the marketing site with Stripe checkout + Neon orders:

# App
NEXT_PUBLIC_APP_URL=https://yourdomain.com

# Stripe
STRIPE_SECRET_KEY=sk_...
STRIPE_PRICE_ID=price_...
STRIPE_WEBHOOK_SECRET=whsec_...

# Database
DATABASE_URL=postgresql://...

# Email / product copy
RESEND_API_KEY=re_...
RESEND_FROM_EMAIL="SigmaNext <[email protected]>"
PRODUCT_NAME=SigmaNext

# GitHub collaborator invite (optional)
GIT_REPO_FULL_NAME=org/private-repo
GIT_TOKEN=ghp_...
Neon DATABASE_URL in Docker / CoolifyDo not wrap DATABASE_URL in single or double quotes in panel env vars (unlike some .env examples). The Neon serverless driver uses new URL(); a leading ' makes the string invalid and webhooks fail to save orders. The app normalizes common quote-wrapping; prefer pasting the raw postgresql://... URL.
Docker build-argsIf you bake env into images via CI, pass secrets as build-args only in trusted pipelines (GitHub Actions with Environment protection). Prefer runtime env injection for truly secret values when possible.