Skip to main content

Environment variables

Environment variables are how a template configures the workload inside it: a Hugging Face token, a model name, a log level. Add them in the Environment section of the template form, one key and value per row, with a secret switch on the right.

Setting them

PartRules
KeyUp to 256 characters. Rows with a blank key are dropped when you save.
ValueAny string. Leaving it empty stores the entry as unset.
SecretMasks the value for anyone outside the owning organization.

An entry with no value is not injected into the container at all. That makes it a good placeholder: declare HF_TOKEN as a secret with no value, and the template documents what a renter must supply without shipping a token to everyone who reads it.

Over the API, env is a list of objects on POST /v1/templates and PATCH /v1/templates/{id}:

{
"env": [
{ "key": "MODEL_ID", "value": "meta-llama/Llama-3-8B", "secret": false },
{ "key": "HF_TOKEN", "value": null, "secret": true }
]
}

Sending env on a PATCH replaces the whole list. There is no per-key update.

Secret masking

A secret value is returned only to the organization that owns the template. Everyone else — including someone browsing your public template, and including a curated system template's readers — gets value: null with the secret flag intact. The console shows the key with a hidden placeholder instead of the value.

The masking follows the data, not the endpoint: GET /v1/templates, GET /v1/templates/{id} and GET /v1/templates/by-hash/{hash_id} all apply it.

Two consequences worth knowing:

  • Duplicating a template your organization does not own blanks every secret value in the copy. You never had read access to them, and becoming the copy's owner must not change that. Duplicating your own template keeps them.
  • Marking an existing value secret hides it going forward, but does not un-share it with anyone who already read it. Rotate the credential instead.

Renter overrides at deploy

A deploy can add or replace environment entries with env_overrides on POST /v1/instances:

{
"offer_id": "…",
"template_id": "…",
"disk_gb": 100,
"env_overrides": [{ "key": "HF_TOKEN", "value": "hf_…", "secret": true }]
}

Template env is applied first, then the overrides, matched by key — the override wins. Entries with a null value on either side are dropped rather than injected as an empty string. This is how you fill a secret placeholder without editing the template, and it keeps your token off a shared recipe.

The platform overlay always wins

After the template env and the renter overrides are merged, Superheat applies a platform overlay, and the overlay is applied last. A key in the overlay cannot be shadowed by a template value or by an env_overrides entry — whatever you set is silently replaced.

VariableSet whenCarries
CONTAINER_IDalwaysthe workload identifier
GPU_COUNTalwayshow many GPUs are assigned to this instance
SUPERHEAT_TCP_PORT_<n>per published TCP portthe host port that container port <n> maps to
PUBLIC_KEYssh, jupyter, when you attach an SSH key at deployyour SSH public key
SUPERHEAT_SSH_PUBLIC_KEYSssh, jupyter, when you attach an SSH key at deploythe same key material, in the newline-separated form
SUPERHEAT_ONSTARTssh, jupyter, when setthe on-start script body
OPEN_BUTTON_PORTssh, jupyter, when a port is labeled openthe Open button target port
JUPYTER_TOKENjupyterthe platform-minted access token
JUPYTER_PORTjupyter8080
JUPYTER_DIRjupyterthe template's Jupyter working dir
JUPYTER_LABjupytertrue for JupyterLab, false for the classic notebook

So setting JUPYTER_TOKEN on a template does nothing: the platform mints the token so it can build the Open button URL, and the token never travels back up the wire. Setting GPU_COUNT does nothing either — it reflects the slice you actually rented, and a program that trusts it would be lied to if a renter could edit it.

Do not name a template variable after an overlay key

The overwrite is silent. If your code reads GPU_COUNT expecting your own value, it will get the platform's instead, with no error anywhere.

What you see inside the container

On a base-derived image, sshd and Jupyter start login shells that do not inherit the container process environment, so the entrypoint writes the environment to /etc/environment and /etc/profile.d/superheat-env.sh. Your variables, plus CONTAINER_ID, GPU_COUNT and the SUPERHEAT_TCP_PORT_* entries, are all there when you SSH in.

Provisioning secrets are deliberately excluded from both files: SUPERHEAT_ONSTART, JUPYTER_TOKEN, PUBLIC_KEY and SUPERHEAT_SSH_PUBLIC_KEYS are consumed by the entrypoint and never re-exported. Echoing $JUPYTER_TOKEN in an SSH session returns nothing, and that is working as designed.