This page classifies every operator-facing value into three classes and gives the exact procedure for each. Read the class before you change anything: class C values are permanent by design, and changing one is how an installation breaks.
| Class | Meaning |
|---|---|
| A — safe to change | Edit and recreate the container; the change takes effect on restart with no side effects. |
| B — changeable, with an effect | The change is possible, but it has a consequence: sessions end, a dependent component must be updated first, or a container must be recreated. |
| C — must not change | Not rotatable. The value is baked into another component or into existing data, and changing it breaks the installation. |
The command used throughout is the standard recreate from the installer's install directory, where
its docker-compose.yml and .env live:
docker compose up -d backend
Edit the value in the installer's .env, then recreate the backend. These values are read at
startup and have no cross-component consequence.
| Value | Procedure | Verification |
|---|---|---|
JWT_ACCESS_EXPIRY | Set the new duration, then docker compose up -d backend | Log in and inspect a fresh access token's expiry; it matches the new duration. Existing sessions keep their old expiry until the token is refreshed |
JWT_REFRESH_EXPIRY | Set the new duration, then docker compose up -d backend | Log in and inspect the refresh-token cookie's max age; it matches the new duration |
NEST_TYPEORM_LOGGING | Set true or false, then recreate | Query lines appear (or stop appearing) in the backend log |
SWAGGER_ENABLED | Set true or false, then recreate | /api/docs loads (or returns not found) |
NEST_ORIGINS | Set the new allowlist, then recreate | A browser request from the allowed origin succeeds; one from another origin is rejected |
TZ | Set the timezone, then recreate | Log timestamps and the container clock reflect the new zone |
NEST_NODE_ENV | Set dev or prod, then recreate | dev adds debug and verbose log lines; prod does not |
Each of these can be changed, but something else changes with it. Do not treat them as routine edits.
JWT_SECRET — ends every sessionRotating the signing secret invalidates every access and refresh token already issued. Every signed-in administrator is logged out and must sign in again. This is the intended way to force a global logout.
Procedure (regenerate by removing the file, then recreating):
docker compose exec -T backend sh -c 'rm -f /usr/src/app/secrets/jwt.secret' docker compose up -d --force-recreate backend
On the next start the installer finds no jwt.secret file and generates a new one.
Verification: a token issued before the change is rejected with an authentication error; a fresh login succeeds.
The backend also keeps a refresh-token table, but it stores only a hash of each refresh token. A token that no longer verifies against the signing secret is simply never presented successfully.
CURATO_SERVICE_TOKEN — update the dependent componentThis shared secret is read by the installer and written into the deployed stack's environment file.
The curato service must receive the new value, or its calls to drive deployments are rejected.
Procedure:
docker compose exec -T backend sh -c 'rm -f /usr/src/app/secrets/curato.token' docker compose up -d --force-recreate backend
Then regenerate the deployed stack's environment file (open Advanced configuration and save, or run
the generation endpoint) and recreate the affected stack services so curato reads the new token.
Verification: the deployment engine accepts a request from curato; a request bearing the old
token is rejected.
VERSION — switches the running buildChanging VERSION by hand and recreating runs a different build of the installer. The supported path
is the installer's own self-update, which pulls the new image, verifies it, and rewrites the compose
file itself; self-update pins the new tag explicitly so an operator-pinned VERSION cannot turn the
update into a silent no-op.
Procedure: prefer Update in the UI. To pin a build manually, set VERSION, then recreate.
Verification: the reported running version and image digest change to the target.
NEST_PORT — move the portNEST_PORT sets both the container's listen port and the published host port. Anything that reaches
the installer on the old port — a reverse proxy, a bookmark, the deployed stack's link back to it —
must be updated first.
Procedure: update the value and any dependant, then docker compose up -d backend.
Verification: the installer answers on the new port and no longer on the old one.
DOCKER_SOCK — repoint the socketOnly change this to match the host's Docker mode (rootful vs rootless). A wrong path leaves the backend unable to drive Docker at all: every deploy, pull and restart fails.
Procedure: set the correct socket path, then docker compose up -d backend.
Verification: the deployment status endpoint reports the container inventory instead of failing.
Saving a value in Advanced configuration writes it to the installer's database and regenerates the deployed stack's environment file. Services pick it up only when they are recreated — use Apply changes, which recreates the affected services in dependency order.
Verification: the stale-services list no longer reports the service for that value after the apply completes.
lurien re-reads the mounted .env but keeps its baked-in environment, so a plain restart can
leave it running mixed configuration. Recreate it with Apply changes, not a restart.
A row whose generator is ed25519-pub:<CODE> is recomputed from the seed held by another row every
time the values are synced. Changing the seed rotates the derived public key automatically. The
component that verifies signatures against that public key must be updated to accept the new key, or
every signature check rejects silently.
Procedure: change the seed row in the UI and save; the derived row is recomputed.
Verification: the derived row shows the new public key; the consumer accepts signatures produced with the new seed.
These values are permanent. Changing or deleting them breaks the installation.
| Value | Why it must not change |
|---|---|
NEST_ENCR_KEY (encr.key) | It encrypts every stored secret value, including AZURE_CLIENT_SECRET and the secret rows of the deployed stack. A new key makes all existing ciphertext undecryptable: the API reports a decrypt error and the stored Azure secret must be re-entered. Never delete or replace this file |
POSTGRES_PASS (pg.pass) | The password is set when the Postgres data volume is first initialised. Deleting the file makes the container generate a new random password on its next start, but the database role still holds the old one — the backend then cannot connect. It is not rotatable without an ALTER ROLE on the live database |
POSTGRES_USER and POSTGRES_DATABASE_NAME | The role and database are created when the volume is first initialised. Changing them afterwards points the backend at a role or database that was never created |
BLOB_ARTIFACT_VARIANT | It selects which published artifacts the installer downloads. It is a development switch and must never be set on a client host — setting it switches the host onto dev artifacts |
AZURE_TENANT_ID and AZURE_CLIENT_ID | Platform identifiers baked into the container environment in the compose file. Changing them requires editing that file, which the self-update overwrites. Treat them as fixed for the life of the install |
DELAMAIN_CHANNEL | Selects the install channel and the self-update tag channel. Changing it points self-update at a different channel than the one the install came from |
DELAMAIN_CONTAINER_NAME | The backend resolves its own running image and compose project by inspecting this container. A wrong value breaks version reporting and self-update |
DEPLOYMENT_DIR and TMPDIR | These paths must be identical host and container for the bind mounts to resolve. Changing one without the other silently hands the self-update helper an empty staging directory |
The installer's compose file and the deployed docker-compose.yml | Both are overwritten by an update. Local edits do not survive — see Compose files and files on disk |
The following are deliberately left unclassified rather than guessed. Confirm them against the published schema or with the team that maintains it before relying on them:
VERSION. The example file ships latest while the compose file falls
back to prod-latest when unset; pin a concrete tag and treat the default as ambiguous.