Rotating values

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.

ClassMeaning
A — safe to changeEdit and recreate the container; the change takes effect on restart with no side effects.
B — changeable, with an effectThe 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 changeNot 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:

bash
docker compose up -d backend

Class A — safe to change

Edit the value in the installer's .env, then recreate the backend. These values are read at startup and have no cross-component consequence.

ValueProcedureVerification
JWT_ACCESS_EXPIRYSet the new duration, then docker compose up -d backendLog 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_EXPIRYSet the new duration, then docker compose up -d backendLog in and inspect the refresh-token cookie's max age; it matches the new duration
NEST_TYPEORM_LOGGINGSet true or false, then recreateQuery lines appear (or stop appearing) in the backend log
SWAGGER_ENABLEDSet true or false, then recreate/api/docs loads (or returns not found)
NEST_ORIGINSSet the new allowlist, then recreateA browser request from the allowed origin succeeds; one from another origin is rejected
TZSet the timezone, then recreateLog timestamps and the container clock reflect the new zone
NEST_NODE_ENVSet dev or prod, then recreatedev adds debug and verbose log lines; prod does not

Class B — changeable, with a stated effect

Each of these can be changed, but something else changes with it. Do not treat them as routine edits.

JWT_SECRET — ends every session

Rotating 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):

bash
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.

Note

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 component

This 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:

bash
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 build

Changing 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 port

NEST_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 socket

Only 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.

Deployed-stack values edited in the UI

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.

Warning

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.

Derived key rows

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.

Class C — must not change

These values are permanent. Changing or deleting them breaks the installation.

ValueWhy 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_NAMEThe 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_VARIANTIt 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_IDPlatform 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_CHANNELSelects 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_NAMEThe 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 TMPDIRThese 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.ymlBoth are overwritten by an update. Local edits do not survive — see Compose files and files on disk

Values this repository cannot classify with confidence

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: