DinD HostingManual
Overview/Manual/Build & deploy
CHAPTER 07

Environment & secrets

Configuration lives outside your source. Set variables in the console, over REST or from an agent — the platform stores them (secrets encrypted) and applies them when the app is recreated.

Three layers#

3 Project variablesUI · Environment tab · REST PUT /projects/{id}/env/{key} · MCP set_envSecrets are encrypted and write-only. Reserved names are rejected.2 platform.yaml env:committed with the source; one value set per keyMay still override a platform-injected name (unchanged behaviour).1 Platform-injectedPORT · PLATFORM_PROJECT · PLATFORM_USER · S3_* (s3: true) · DB_<NAME>_* (databases:)Always present; the platform’s own contract with your app.a later layer overrides the same nameApp containerthe effective environmentbuilt on every deploy andevery recreate
The environment of the app container is built from three layers, lowest to highest. A later layer overrides the same name.
  1. Platform-injected — always PLATFORM_PROJECT, PLATFORM_USER and PORT; with s3: true also S3_ENDPOINT, S3_BUCKET, S3_ACCESS_KEY, S3_SECRET_KEY; for every database in databases: the five DB_<NAME>_* variables.
  2. platform.yaml → env — constants committed with the source.
  3. Project variables — what you manage on the Environment tab. This layer wins; it can never shadow a platform name, because reserved names are rejected.

The Environment tab#

hosting.example.com/projects/7
Environment
The Environment tab. (1) the banner reminds you that changes apply on recreate, (2) a secret shows as four dots and can only be replaced, never read, (3) add, edit and delete.

Press + add variable, give it a name and a value, and tick secret when the value is a credential. Secrets are stored encrypted and shown as ••••. When you edit one the field starts empty — typing a new value replaces it.

After any change the tab says Saved, not applied yet. The running app keeps its old environment until you press recreate app now (a few seconds of downtime, volumes kept) or deploy again.

Rules#

Rule Value
Name [A-Za-z_][A-Za-z0-9_]*, at most 128 characters
Reserved (rejected) PORT, anything starting with PLATFORM_, S3_ or DB_
Value at most 8 KiB
Count at most 100 variables per project
Multi-line secrets set through REST or MCP; the console field is single-line

Runtime only

Variables are not visible to the image build. npm run build, pip install and friends do not see them. Put build-time configuration in platform.yaml build_cmd/install_cmd, or read the variable when the app starts.

Write-only secrets#

A secret's value is returned by no path — not the console, REST, MCP, audit rows, logs or error messages. The only way to change it is to set it again. The App tab and GET /projects/{id}/app list the names the app receives and their origin (platform, platform.yaml, project variable), with a secret badge where it applies — never the values.

Anything you give an agent is part of the conversation

With the MCP tool set_env the value travels through the agent's context. Use set_env for harmless configuration and set real credentials in the console.

REST and MCP#

bash
# list (secret values are always null)
curl -fsS "$BASE/api/v1/projects/$PID/env" -H "Authorization: Bearer $TOKEN"

# create or update
curl -fsS -X PUT "$BASE/api/v1/projects/$PID/env/LOG_LEVEL" \
  -H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/json' \
  -d '{"value":"debug","is_secret":false}'

# delete (a platform.yaml value of the same name applies again)
curl -fsS -X DELETE "$BASE/api/v1/projects/$PID/env/LOG_LEVEL" -H "Authorization: Bearer $TOKEN"

# apply
curl -fsS -X POST "$BASE/api/v1/projects/$PID/app/recreate" -H "Authorization: Bearer $TOKEN"
list_env(project=7)
set_env(project=7, key="LOG_LEVEL", value="debug", is_secret=false)
unset_env(project=7, key="LOG_LEVEL")
app_recreate(project=7)

set_env returns {key, is_secret, value, created, note}; the value is null for secrets.

Which layer set this variable?#

Open the App tab: the Environment card lists every variable name with a from column. A name that appears once in the list has exactly one source; a name you set in platform.yaml and as a project variable shows the winner — the project variable.