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.