Environment Variables: Best Practices
What belongs in env vars
Put in env vars:
• API keys and secrets (Stripe, OpenAI, Resend, etc.)
• Database connection strings
• Feature flags
• Service URLs that differ between environments
Never put in env vars:
• Your entire application config (use a config file)
• Binary data (use file storage)
• Values that change per-request (use session or headers)
Naming conventions
Use SCREAMING_SNAKE_CASE. Be descriptive:
OPENAI_API_KEY (not KEY or API)
DATABASE_URL (not DB)
STRIPE_WEBHOOK_SECRET (not STRIPE_SECRET, which is ambiguous)
Prefix by service to avoid collisions:
RESEND_API_KEY, STRIPE_SECRET_KEY, SUPABASE_SERVICE_ROLE_KEY
Secrets vs non-secrets
Secrets (rotate if leaked): API keys, tokens, passwords, signing keys. Store in MoonBase env vars, never in your repo.
Non-secrets (safe to commit): feature flags, public API endpoints, app names, locale settings. These can go in a committed .env.example file.
Loading env vars from a .env file
Include a .env file in your ZIP root — MoonBase reads it automatically before building. Variables in the MoonBase dashboard override variables in the .env file.
Format:
DATABASE_URL=postgresql://...
NEXT_PUBLIC_APP_URL=https://your-site.moonbase.host
After changing env vars
Changes to env vars take effect on the NEXT deploy. Dynamic sites (Next.js, Node.js) inject env vars at startup — the running container doesn't see new values until restarted. Redeploy your mission (even with the same ZIP) to apply env var changes.
Public vs private variables (Next.js)
In Next.js, variables prefixed with NEXT_PUBLIC_ are embedded in the client bundle and visible to browsers. All other variables are server-only.
Use NEXT_PUBLIC_ for: public API endpoints, analytics IDs, app URLs.
Never use NEXT_PUBLIC_ for: secret keys, tokens, database URLs.