DocsDeploysEnvironment variables

Configuring environment variables

Environment variables carry configuration and credentials into your service at runtime. This page covers per-service values, shared environment groups, platform-provided variables and build-time behaviour.

Every Muerte Cloud service reads its configuration from environment variables — database URLs, API keys, feature flags, ports. Values are injected into both the build and the runtime process, with sensitive values encrypted at rest and never printed to logs.

Changes trigger a redeploy
Editing, adding or removing an environment variable queues a fresh deploy — a new instance boots with the updated values and traffic swings over once it's healthy. Restarts alone do not pick up new values; a full deploy is required.

Adding environment variables#

Open the service's Environment tab and add entries one by one, or paste a .env file and Muerte Cloud will parse it:

bash
DATABASE_URL=postgres://user:pass@host:5432/app
REDIS_URL=redis://cache.internal:6379
STRIPE_SECRET_KEY=sk_live_...
LOG_LEVEL=info

Names are case-sensitive and must match [A-Z_][A-Z0-9_]*. Values can contain any UTF-8; wrap them in quotes if they include spaces or shell metacharacters.

Generated values

Muerte Cloud can generate a strong random value for any variable — useful for session secrets, JWT keys and webhook signing secrets. The value is created once, stored encrypted and never shown again after the first reveal.

Environment groups#

An environment group is a named bundle of variables that you link to one or more services. Update the group once and every linked service redeploys with the new values — no copy-pasting between staging and production.

Shared credentials
Keep DB URLs, third-party API keys and OAuth secrets in one place. Link staging and production to different groups.
Per-environment overrides
Any variable set directly on a service wins over the same key from a linked group.
Audit trail
Every edit records who changed what and when. Rotate a secret and see exactly which services picked it up.
Scoped access
Workspace roles control who can read or edit a group. Members without access see redacted values.

Resolution order

When a service starts, variables are resolved in this order — later entries override earlier ones:

  1. 1
    Platform-provided
    Built-in variables injected by Muerte Cloud (see below).
  2. 2
    Linked environment groups
    Merged top-down in the order they're attached to the service.
  3. 3
    Service-level variables
    Values set on the service itself. Always win over any group.

Platform-provided variables#

Muerte Cloud injects a small set of read-only variables into every deploy. You can reference them from your app but not overwrite them.

FieldDescription
PORTThe port your web service must bind to. Defaults to 8080.
MUERTE_SERVICE_IDStable identifier of the current service, e.g. srv-01H9….
MUERTE_SERVICE_NAMEHuman-readable service name from the dashboard.
MUERTE_SERVICE_TYPEOne of web, static, private, worker or cron.
MUERTE_INSTANCE_IDUnique per running instance. Changes on every deploy and restart.
MUERTE_GIT_COMMITFull SHA of the commit that produced this release.
MUERTE_GIT_BRANCHTracked branch name for this service.
MUERTE_EXTERNAL_URLPublic https URL of the service, if any.

Build-time vs runtime#

Environment variables are available in both stages, but the two stages run in separate sandboxes:

FieldDescription
BuildThe build container sees every variable. Frameworks like Next.js and Vite can bake NEXT_PUBLIC_/VITE_ values straight into the bundle.
RuntimeThe runtime instance sees the same values, plus platform-provided variables. Any edit after build requires a fresh deploy to reach the client bundle.
Client bundles are public
Anything prefixed with NEXT_PUBLIC_, VITE_ or a similar public marker ends up in JavaScript shipped to browsers. Never put real secrets there — keep server-only keys unprefixed so they stay on the instance.

Reading values in your code#

Standard language APIs work unchanged:

node.js
javascript
const dbUrl = process.env.DATABASE_URL;
const port = Number(process.env.PORT ?? 8080);
python
python
import os
db_url = os.environ["DATABASE_URL"]
port = int(os.getenv("PORT", "8080"))
go
go
dbURL := os.Getenv("DATABASE_URL")
port := cmp.Or(os.Getenv("PORT"), "8080")

Best practices#

One group per environment
Keep production, staging and preview in separate groups. Prevents an edit for staging from leaking into prod.
Rotate on a schedule
Regenerate signing keys and third-party tokens periodically. Deploys are zero-downtime, so rotation is cheap.
Never commit .env
Add .env* to .gitignore. Muerte Cloud is the source of truth; commits leak into forks and CI logs.
Prefer references over duplication
Link the same group to multiple services instead of copy-pasting values. One edit updates every consumer.