The DataMind Installer reads two different environment files, and confusing them is the most common configuration mistake. Keep them apart:
.env next to the installer's
docker-compose.yml on the host. Docker Compose reads it for variable interpolation and
passes it into the installer's own containers. This page documents it fully.deployment/.env inside its container) from a published schema and writes it for the DataMind OS
services it deploys. Its variable list is defined outside this repository; see
The deployed stack's environment file.Values in the installer's own .env are interpolated by Docker Compose before the containers
start. To change any of them you edit the file and recreate the container — see
Rotating values for which changes are safe.
Every variable below is present in .env.example, injected by the compose file, or read directly by
the backend. Default is the value shipped in .env.example or the fallback in code.
| Variable | Type | Default | Required | Controls | Effect of changing |
|---|---|---|---|---|---|
VERSION | string (image tag) | latest | No | Image tag the installer runs as, and the tag the self-update helper pulls | Switching it and recreating changes the running build; the supported path is self-update, which pins the tag itself |
DELAMAIN_IMAGE | image reference | injected by compose as unistream.azurecr.io/delamain:${VERSION}; code fallback delamain | No | Image used to spawn the self-update helper and the host-migration helper | Must match the running image, or the helpers run the wrong build |
DELAMAIN_CHANNEL | string | prod (compose); dev in the dev compose | No | Install channel; selects the published compose file to compare against and the self-update tag channel | Repoints self-update at another channel — do not change after install |
DELAMAIN_CONTAINER_NAME | string | delamain-backend (code); delamain-backend-dev in dev compose | No | Name of the container the backend inspects to resolve its own running image and compose project | Wrong value breaks version reporting and self-update |
ACR_URL | host name | unistream.azurecr.io (code); unistreamdev.azurecr.io in dev compose | No | Container registry host pulled from | Wrong host fails every image pull |
BLOB_ARTIFACT_VARIANT | enum: empty or dev | empty (production artifacts) | No | Selects the published artifact pair: production schema + compose, or the dev pair | Never set on a client host — it switches the installer onto dev artifacts |
DOCKER_SOCK | host path | /var/run/docker.sock | No | Host path of the Docker socket bind-mounted into the backend | Must point at the correct socket (rootful vs rootless); wrong value leaves the backend unable to drive Docker |
NEST_PORT | integer | 8000 | No | Port the backend listens on, and the host port published by compose | Changes both the listen port and the published port; a reverse proxy or client using the old port must be updated first |
NEST_NODE_ENV | enum: dev or prod | prod | No | Log verbosity and production cookie-domain behaviour | dev raises log verbosity; production cookie handling depends on prod |
SWAGGER_ENABLED | boolean | false | No | Serves the OpenAPI UI at /api/docs | Turning it on exposes the API surface; turning it off removes the route |
TZ | string | UTC | No | Container timezone | Changes the local timezone used by the container's clock |
NEST_TYPEORM_LOGGING | boolean | false | No | TypeORM query logging | Turning it on logs every SQL statement — verbose and not for production |
NEST_ORIGINS | comma-separated list | http://localhost:8000 | No | CORS allowlist | Only relevant when the UI is served from a different origin; irrelevant in the default same-origin setup |
POSTGRES_HOST | string | postgres (injected by compose) | No | Database host | Points the backend at another database |
POSTGRES_PORT | integer | 5432 (injected by compose) | No | Database port | Points the backend at another database port |
POSTGRES_USER | string | postgres | No | Database user | Changes the role the backend and the Postgres container use; must match the role in the data volume |
POSTGRES_DATABASE_NAME | string | delamain | No | Database name | Changing it after first start points the backend at a database that was never created |
JWT_ACCESS_EXPIRY | duration string | 30m | No | Lifetime of an access token | Longer tokens stay valid longer; applies to newly issued tokens |
JWT_REFRESH_EXPIRY | duration string | 7d | No | Lifetime of a refresh token | Longer refresh windows mean longer-lived sessions |
AZURE_TENANT_ID | UUID | none in code; set by compose | Yes (validated non-empty) | Azure AD tenant used for registry and blob authentication | The backend refuses to start if it is empty; changing it breaks registry blob and ACR authentication |
AZURE_CLIENT_ID | UUID | none in code; set by compose | Yes (validated non-empty) | Azure AD application (client) id | The backend refuses to start if it is empty; changing it breaks Azure authentication |
AZURE_CLIENT_SECRET | string | none | No | Azure AD client secret | Not an .env value — stored encrypted in the database and set through the UI (see Secrets) |
MIGRATE_HOST_SCRIPT_PATH | host path | /opt/delamain/migrate-host.sh | No | Where the host-migration script is copied before it runs | Must be a path the migration helper can execute inside the host's namespaces |
MIGRATE_HOST_DIR | host path | /opt/delamain | No | Host directory bind-mounted into the backend at the identical path | Used only by compose; must stay consistent with MIGRATE_HOST_SCRIPT_PATH |
JENKINS_HOME | host path | /var/lib/jenkins | No | Jenkins home bind-mounted read-only into the backend | Feeds the migration-time config.xml import |
SECRETS_DIR | path | ./secrets in code; /usr/src/app/secrets via the mounted volume | No | Directory the generated secret files are read from and written to | Must stay the mounted volume, or generated secrets are lost on recreate |
DEPLOYMENT_DIR | container path | /usr/src/app/deployment (compose) | No | Directory holding the deployed stack's downloaded compose file and generated .env | Must stay the bind-mounted path that maps to the host ./deployment |
TMPDIR | path | /var/tmp/delamain | No | Temp directory; also the parent of the self-update staging directory | Must be bind-mounted at the same path host and container, or the helper receives an empty staging directory |
JWT_SECRET | string | generated on first boot | No | JWT signing secret | Set from the jwt.secret file at runtime; overriding it would break existing sessions |
NEST_ENCR_KEY | base64 string | generated on first boot | No | AES-256-GCM key that encrypts stored secret values | Set from the encr.key file at runtime; changing it makes stored secrets undecryptable |
POSTGRES_PASS | string | generated on first boot | No | Database password | Read from the pg.pass file; not set in .env |
CURATO_SERVICE_TOKEN | string | generated on first boot | No | Shared secret the curato service presents to drive deployments | Read from the curato.token file, and written into the deployed stack's .env |
VERSION is the single knob for which build of the DataMind Installer runs. The compose file
defaults it to prod-latest when unset, while .env.example ships latest; pin a concrete tag for
production hosts so a restart cannot silently move the running build.
DELAMAIN_IMAGE is derived from the same tag and is used whenever the installer has to start a
sibling container: the self-update helper (a detached container built from the new image) and the
host-migration helper. DELAMAIN_CONTAINER_NAME must match the container the installer actually
runs in, because version reporting and self-update resolve the running build by inspecting that
container, not by reading the tag.
BLOB_ARTIFACT_VARIANT selects which published artifact pair the installer downloads — the
production schema and compose, or the dev pair. It is deliberately independent of
NEST_NODE_ENV, so raising log verbosity can never switch a host onto dev artifacts. Leave it empty
on any client host.
DOCKER_SOCK is the host path of the Docker socket bind-mounted into the backend. The deploy engine
drives docker compose through this socket, so access to it is equivalent to host root. Standard
(rootful) Docker uses /var/run/docker.sock. For rootless Docker, point it at the rootless socket,
for example /run/user/1000/docker.sock (find the UID with id -u).
NEST_PORT controls the port the backend listens on and the host port compose publishes; both come
from the same variable, so changing it moves the UI and API together. In the default setup the
installer serves the SPA and the API from the same origin, which is why NEST_ORIGINS is described
as irrelevant unless you repoint the UI at the backend from a different origin.
NEST_NODE_ENV selects log verbosity: prod restricts the logger to error, warn, log and fatal;
dev adds debug and verbose. It also gates production cookie behaviour. SWAGGER_ENABLED serves
the OpenAPI UI at /api/docs.
POSTGRES_HOST and POSTGRES_PORT are injected by the compose file (the postgres service name on
the compose network) rather than set in .env, because the backend and the init job must reach the
database over the compose network. POSTGRES_USER and POSTGRES_DATABASE_NAME are interpolated into
both the Postgres container and the backend, so the two stay in step. The password is never in
.env — see Secrets.
JWT_ACCESS_EXPIRY and JWT_REFRESH_EXPIRY set token lifetimes. Both are read once when the auth
service starts, so a change applies to tokens issued after the next restart. JWT_SECRET is not an
.env value: it is generated into the secrets volume on first boot and loaded at runtime.
AZURE_TENANT_ID and AZURE_CLIENT_ID are the only two variables the backend validates as
mandatory: the application throws on startup if either is empty. They identify the Azure AD
application used to authenticate to the container registry and blob storage. The matching client
secret is stored encrypted in the database, not in .env.
DEPLOYMENT_DIR is the container path of the directory that holds the deployed stack's compose file
and generated .env; compose bind-mounts the host ./deployment there, so the files survive a
container recreate. TMPDIR must be bind-mounted at the same path host and container — the
self-update helper deliberately relies on that identity to receive staged files. MIGRATE_HOST_DIR
and MIGRATE_HOST_SCRIPT_PATH locate the host-migration script, and JENKINS_HOME exposes the
existing Jenkins configuration read-only for the migration-time import.
These four values never appear in .env. They are generated on first boot and stored in the
delamain_secrets volume:
JWT_SECRET — a 64-byte hex value, written to jwt.secret, injected as JWT_SECRET.NEST_ENCR_KEY — a 32-byte base64 value, written to encr.key, injected as NEST_ENCR_KEY.POSTGRES_PASS — a random hex value written to pg.pass by the Postgres container itself, then
read by the backend.CURATO_SERVICE_TOKEN — a 48-character alphanumeric value, written to curato.token, injected as
CURATO_SERVICE_TOKEN, and additionally written into the deployed stack's .env.Their creation, storage and rotation are covered in Secrets and Rotating values.
The installer generates a second environment file for the DataMind OS services it deploys. It is
written from the rows stored in the installer's own database, which are seeded from a published
schema template (.env.unified.template, downloaded from blob storage). The concrete variable names
in that file — PLATFORM_URL, the per-service memory and port variables, and the rest — are defined
by that published schema and are not enumerated in this repository. This page therefore does not
list them. Behaviour that is defined in this repository:
CURATO_SERVICE_TOKEN is appended to the file from the generated token, not from a database
row, so no operator edit can drift it away from the value the installer compares against.<USER> substitution. Any value containing the literal <USER> is replaced with the stored VM
user when the file is written.${PLATFORM_URL} interpolation. Values that reference ${PLATFORM_URL} are placed after the
plain values so Docker Compose resolves them in read order.ed25519-pub:<CODE> is the Ed25519 public key of the
seed held by another row; it is recomputed whenever that seed changes.For the service names and groups these rows attach to, see Service catalog.
The installer's own .env is separate from this generated file. Editing values in the UI changes
the deployed stack, not the installer.