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. moonbase also won't auto-apply a secret-shaped value even if it's present in a shipped .env file — see 'Loading env vars from a .env file' below.
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
If your ZIP includes a .env file, moonbase reads it before building and applies non-secret values automatically. Anything shaped like a real credential — API keys, tokens, passwords, or a connection string with an embedded password — is never auto-applied even if it's in the file; you'll be prompted to set those from Mission Control → Environment Variables instead, the same write-only field. Variables set in the moonbase dashboard always override whatever's in the .env file.
Safe-to-ship format:
NEXT_PUBLIC_APP_URL=https://your-site.moonbase.host
FEATURE_FLAG_NEW_UI=true
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.