Skip to content

Environment variables

Give a service its configuration and secrets: set variables one at a time or from a .env file, decide whether the build or the running container sees them, and read the variables HostStack sets for you.

How variables work

Each service has its own set of variables. Every value is encrypted at rest with AES-256-GCM, whether or not you mark it secret. A variable reaches your code the next time the service deploys — changing one does not restart anything by itself, so deploy afterwards (or push a commit) to pick it up.

Variables can also come from an env group shared across services, from a linked database, and from HostStack itself. Which one wins when two set the same key is covered under Precedence.

Set a variable

In the dashboard, open the service, go to Settings → Variables, and fill in the row at the bottom of Service Variables: key, value, Inject into and the Secret switch. From a terminal:

# Create or update — the CLI looks the key up and updates it if it exists
hoststack env set svc_... NODE_ENV=production
hoststack env set svc_... STRIPE_SECRET_KEY=sk_live_... --secret --target runtime

hoststack env list svc_...
hoststack env get svc_... NODE_ENV
hoststack env delete svc_... NODE_ENV

Keys are case-sensitive and stored exactly as you write them: they must start with a letter or underscore and contain only letters, digits and underscores, up to 256 characters. FOO and foo are two different variables, as they are inside the container. A value can be up to 32,768 characters.

Build, runtime or both

Every variable has a target that decides who can read it. The dashboard calls it Inject into; the CLI, SDK and API call it target.

TargetDashboardWho sees it
bothBuild + RuntimeThe running container, and the build — unless the variable is also secret. This is the default.
runtimeRuntime onlyOnly the running container. Never reaches the build.
buildBuild onlyOnly the build, and withheld from the running container. Honoured for secrets too: this is how you hand a build a private-registry token.

A secret on both is runtime-only. Values given to a build can end up in the image's history, so HostStack never sends a secret to the build unless you choose Build only for it explicitly.

Secrets

Mark a variable Secret (--secret in the CLI, isSecret: true in the SDK) and its value is replaced by •••••• in the dashboard, in hoststack env list and in every API response. Your app still receives the real value.

The eye icon next to a secret in the dashboard reveals it. Every reveal is recorded in the team's activity log with who, when and from which IP address.

Import a .env file

The CLI and SDK send the file to HostStack, which reads it strictly: a line whose meaning depends on the reader — an unquoted $ as in a bcrypt hash, an unquoted #, a key written twice — is refused with its line number instead of guessed at. Nothing is written until you pass --apply.

bash
# Dry run: prints what would be added, changed or refused
hoststack env import svc_... .env.production

# Write it. Imported variables are runtime-only secrets unless you say otherwise.
hoststack env import svc_... .env.production --apply

# Also delete every variable that is not in the file
hoststack env import svc_... .env.production --apply --replace

After an apply, every value is read back from storage and compared byte for byte with the file. The import refuses PORT and any HOSTSTACK_* key, because HostStack sets those itself on every deploy. At most 1,000 variables per file. Use --target and --no-secret to change the defaults.

The dashboard's Import .env button, on the same Variables tab, parses pasted text in the browser and merges it — or replaces everything when Replace all existing variables is on.

Secret files

For credentials that have to be a file — a TLS key, a service-account JSON, a .npmrc — use Settings → Secrets on the service. Give the file a display name, the absolute path to mount it at (for example /etc/ssl/cert.pem), and its content.

  • The file is mounted read-only into the running container on the next deploy.
  • Its content is encrypted at rest and never shown again after you save it.
  • Files are limited to 1 MB of base64-encoded content, roughly 750 KB of file. The path must start with / and may not contain ...
  • Secret files are not available during the build.

Variables HostStack sets

Every deploy sets these in the container. You don't set them, they refresh on each deploy, and they override a variable of the same name that you set yourself.

PORT
number

The port your app must listen on, on 0.0.0.0. HostStack routes to and health-checks exactly this port, so binding anything else fails the deploy. It is the port in the service's settings (or a port: in hoststack.yaml), 3000 unless you changed it.

HOSTSTACK_COMMIT_SHA
string

The full 40-character commit this deploy built. Absent when the deploy has no commit, so fall back rather than assume it is set.

HOSTSTACK_COMMIT_SHORT_SHA
string

The same commit, first 7 characters.

HOSTSTACK_RELEASE
string

The same commit again, under the name error reporters look for. Send it as release when you report an error, and each report is labelled with the code of the container that raised it — not whichever deploy happened to be live when it arrived.

HOSTSTACK_BRANCH
string

The branch this deploy was built from.

HOSTSTACK_DEPLOY_ID
string

The deploy's id (dpl_…). Unique per deploy, so it tells apart two deploys of the same commit.

HOSTSTACK_SERVICE_NAME
string

The service's name, as shown in the dashboard.

HOSTSTACK_SERVICE_ID
string

The service's stable id (svc_…).

HOSTSTACK_PROJECT_ID
string

The numeric id of the project the service belongs to.

HOSTSTACK_TEAM_ID
string

The numeric id of the team that owns the service.

HOSTSTACK_INTERNAL_URL
string

The service's platform hostname, such as web-a1b2.hoststack.dev — a bare hostname with no scheme. Despite the name, it is the public address, not a private one. To call another service privately, use the *_INTERNAL_URL variables described under Networking.

HOSTSTACK_TMP_DIR
string

A writable scratch directory. The container's root filesystem is read-only; /tmp is memory-backed and emptied whenever the container is replaced. Use a volume for anything you need to keep.

Default: /tmp

HOSTSTACK_DEV_HOST
string

Dev boxes only: the box's public dev URL hostname, for your dev server's allowed-hosts list.

HostStack also sets *_INTERNAL_URL for each sibling service and DATABASE_URL-style variables for linked resources. Those are different: your own value for the same key wins, and an empty value switches them off. See Networking.

Report the live version

The usual reason to reach for these is to say which version is running:

A /version endpoint
import os

COMMIT = os.getenv("HOSTSTACK_COMMIT_SHA", "unknown")

@app.get("/version")
def version():
    return {"commit": COMMIT, "deploy": os.getenv("HOSTSTACK_DEPLOY_ID")}

The commit is also passed to your image build as the build argument HOSTSTACK_COMMIT, for when it must be baked in at build time — stamping a version into a compiled frontend bundle, for example. Declare ARG HOSTSTACK_COMMIT in your own Dockerfile, or use $HOSTSTACK_COMMIT in the service's build command.

Reference other resources in a value

A value can contain a template that HostStack fills in at deploy time, in build and runtime variables alike:

TemplateBecomes
${{databases.<ALIAS>.<field>}}A field of a linked resource, by its link alias: url (or connectionString), host, port, database, username, password.
${{services.<name>.<field>}}A sibling service's private address, by its slug or name: url, host or port.
${{service.url}}This service's own public address — its primary custom domain once one is active, otherwise its *.hoststack.dev hostname. ${{service.host}} is the same without the scheme.
bash
hoststack env set svc_... 'READ_REPLICA_URL=${{databases.REPLICA.url}}'
hoststack env set svc_... 'WEBHOOK_URL=${{service.url}}/hooks/stripe'

A template that doesn't resolve — a typo in the alias or field — is left in the value exactly as written, so you can spot it rather than get an empty string. Adding a custom domain redeploys the service, which moves ${{service.url}} onto it.

Precedence

When the same key comes from more than one place, the higher row wins:

#Source
1Variables HostStack sets — PORT and HOSTSTACK_*
2Variables set on the service
3Env groups, in their own order
4Sibling *_INTERNAL_URL variables and linked-resource variables such as DATABASE_URL
5env: in hoststack.yaml

Next steps

Essential cookies only — for login sessions. No tracking. Details