Skip to content
Dashboard
Configure 6 min read

Environment Variables

Configure build-time and runtime values for a NexHost service without committing them to source.

Environment Variables#

Environment variables are how a NexHost service receives values that should not live in source control — database connection strings, third-party API credentials, feature flags, and public client configuration. You set them on the service configuration screen in the dashboard; the platform makes them available at the right moment in the deployment lifecycle.

Keeping configuration out of the repository keeps your history clean and your secrets auditable: a variable can be rotated or removed without rewriting commits.

When to use this#

Use environment variables whenever a value differs between environments, is secret, or would otherwise require editing source between local development and production. Typical examples:

  • DATABASE_URL or a Postgres connection string that points at the managed database for the workspace.
  • API keys for payment, email, or storage providers.
  • A NODE_ENV or framework feature flag you want to flip without a code change.
  • The platform-injected PORT that every public Node runtime must read.

Do not use environment variables as a substitute for a proper build artifact: changing a build-time value on a static site still requires a redeployment so a new artifact can be produced.

Scopes#

Each variable can be available during one or both parts of a deployment. Setting the wrong scope is a common source of "works locally, fails in deployment" behavior, so pick deliberately.

ScopeUse it whenWhat happens if you change it
BuildA build tool needs the value while generating the application output — for example, a static site that inlines a public API URL at build time.The value is baked into the produced artifact. Change it and deploy again so a new build can run.
RuntimeThe running process needs the value after it starts — for example, a database password read at startup or an API key used per-request.The running process receives the value at start. Redeploy or restart the service after changing values that affect startup.
BothThe value is required during the build and by the running service — for example, a Next.js app that compiles with NEXT_PUBLIC_ values and also reads a server flag at runtime.Both of the above apply. Treat the change as a full redeployment trigger.

Static-site values are incorporated into the built output. Change a build-time value and deploy again so a new artifact is produced. Runtime services receive their runtime configuration when they start; redeploy or restart the service after changing values that affect startup.

Info

A variable scoped to Build only will not be present at runtime, and a variable scoped to Runtime only will not be present while the build runs. If a build needs to read a value, scope it to Build or Both; if the running server needs to read it, scope it to Runtime or Both.

Set a value#

  1. Open the service settings in the dashboard.
  2. Add the key, value, and appropriate scope (Build, Runtime, or Both).
  3. Save the configuration. The dashboard confirms which services are affected.
  4. Start a deployment when the change needs a new build or runtime process — most changes do. Do not assume a save alone re-provisions a running container.

Good habits:

  • Use descriptive keys and group related values (DATABASE_URL, REDIS_URL, STRIPE_SECRET_KEY) so future readers can tell secrets from feature flags.
  • Prefer one change per deployment when you are debugging. Updating one variable at a time makes the build log diff small and useful.
  • Keep a short local .env.example (committed) alongside a real .env (ignored) so teammates know which keys exist without sharing values in Git.

Keep secrets server-side#

Do not use browser-exposed variables for credentials. Frontend frameworks may embed specially prefixed values into client-side bundles — for example, Next.js inlines NEXT_PUBLIC_* at build time and Vite inlines VITE_*. Any value with such a prefix will be visible to anyone who can load the page, regardless of server security.

Rules of thumb:

  • If the value is a password, token, private key, or connection string, it must never carry a client-side prefix. Scope it to Runtime (or Both only when the server build needs it) and read it only from server code.
  • If the value is intentionally public (an analytics ID, a public API origin, a feature label shown in the UI), make that intent explicit in the key name and scope it appropriately — typically Build or Both so the client build can inline it.
  • Check your framework’s documentation before putting any sensitive value in a build-time variable. The dashboard cannot undo a client-bundle leak.
Warning

Do not paste real secrets into logs, support tickets, screenshots, or chat messages. When you need to share diagnostic output, redact values first and keep only the key names.

Runtime port#

Public Node services receive PORT from the runtime. Do not replace it with a hard-coded port; configure the application to listen on the provided value instead.

Typical correct patterns:

ts
// Express / generic Node
const port = Number(process.env.PORT);
if (!Number.isFinite(port)) throw new Error("PORT is required");
app.listen(port, "0.0.0.0");
js
// Next.js package.json — let the platform choose the port
{ "scripts": { "start": "next start -p $PORT" } }

Binding to 0.0.0.0 rather than 127.0.0.1 is part of the contract: NexHost verifies TCP reachability through the platform network, not a local loopback inside the container.

Troubleshooting#

SymptomLikely causeFix
Static site shows an old public URL after you updated a variableValue was build-time and the site is still serving the previous artifactStart a new deployment so a new build can inline the value.
Runtime crash: "PORT is required" or connection refusedApplication hard-coded a port or did not read process.env.PORTRead PORT at startup, bind to 0.0.0.0, and redeploy.
Client bundle exposes a key you thought was secretVariable had a client-side prefix (NEXT_PUBLIC_, VITE_) or was inlined into static outputRename to a server-only key, scope to Runtime, and redeploy; rotate the exposed secret where it was issued.
Build succeeds locally but fails remotely with a missing variableScope was Runtime-only, so the build could not read the valueChange scope to Build or Both and redeploy.
  • Deployment Troubleshooting — diagnose build vs runtime failures from the detail page.
  • Logs — read each deployment stage and share output safely.
  • Services Overview — understand which service types even need a start command and PORT.