← BLOG

Environment variables for apps, done properly

Where the token goes, why .env does not get deployed, and how to stop a leaked secret from being a rewrite.

RUNNING APPS · 8 JULY 2026 · 5 MIN READ

Almost every "works locally, broken deployed" bug is an environment variable. The fix is quick; understanding why it happens stops it recurring.

Why your .env did not come with it

A .env file is a local convenience. It is in your .gitignore, it is excluded from deploys, and that is correct. Secrets in a repository are one leaked clone away from being public, and rotating a token is much worse than setting one.

So the values have to be set again wherever the bot runs. Your code does not change: it still reads process.env or os.environ. Only the source of those values moves.

JS
const token = process.env.DISCORD_TOKEN;
if (!token) throw new Error('DISCORD_TOKEN is not set');

client.login(token);
Same code locally and deployed. Only where the value comes from differs.

That explicit check is worth the two lines. An app that fails immediately with a clear message beats one that fails deep inside a library with a generic authentication error.

Write-only is the property that matters

A secret you can read back out of a dashboard is a secret that anything with access to that dashboard can exfiltrate, including a browser extension, a shoulder, or an AI assistant you have connected to it.

Write-only storage removes that. You can replace a value, you cannot retrieve it. On Spocket that is how environment variables work: encrypted at rest, never printed in logs, never shown back to you or to a connected tool.

What belongs in an environment variable

  • App tokens and API keys
  • Database connection strings
  • Webhook URLs that act as credentials
  • Anything that would be bad in a screenshot

What does not: your command prefix, your feature flags, your channel IDs. Configuration that is not secret is easier to read, review and change in code than in a panel, and putting it in the environment scatters your settings across two places.

If a token leaks

  1. 01
    Reset it firstIn the Discord Developer Portal. The old token stops working immediately, which is the point. Do this before cleaning up.
  2. 02
    Update where the app runsSet the new value and restart. The app will not reconnect until you do.
  3. 03
    Then deal with the repositoryRewriting history is optional and often unnecessary once the token is dead. Do not let it delay step one.

A note on AI assistants

If an assistant can read your environment, it can put those values in its context, and from there into a log, a bug report, or a message. Prefer a setup where the assistant can set a variable and never read one. That keeps the convenience and removes the exposure.

Need somewhere to put it?

Spocket runs apps, workers and scrapers that have to stay awake. Deploy from Claude or Cursor by asking, from $3/mo. First app is free for 7 days, no card.

Deploy an appRead the quickstart
Spocket
BlogDocsTermsPrivacyHome