The DataMind Installer exposes a small, deliberate HTTP surface: one public health endpoint, and authenticated endpoints that report the running build and the state of the DataMind OS stack it manages.
GET /api/health is public — it needs no token — and is both the liveness and the readiness
probe. It runs SELECT 1 against the Installer's database and answers:
{ "status": "ok", "db": "up" }If the database is unreachable it returns 503 Service Unavailable with the message
Database connection failed, and logs Health check failed — DB unreachable: <reason>.
curl -s http://localhost:${NEST_PORT:-8000}/api/healthThe Installer's own container healthcheck calls exactly this endpoint, so the same signal drives Docker's health status:
test: ['CMD-SHELL', 'wget -qO- http://localhost:${NEST_PORT:-8000}/api/health || exit 1']
interval: 10s
timeout: 5s
retries: 5
start_period: 20sdocker compose up --wait blocks on that healthcheck, which is why the self-update helper can
verify a switch without polling. The same healthcheck exists on delamain-postgres
(pg_isready) and delamain-backend-init runs as a one-shot to completion.
/api/health says nothing about the DataMind OS stack. It proves the Installer process and its
database are alive. Use GET /api/deployment/status for the managed services.
GET /api/version (authenticated) returns the image reference the container was created from and
the registry digest of the image actually running:
{ "image": "unistream.azurecr.io/delamain:prod-latest", "digest": "sha256:9f3c1a…" }The digest is the exact identity and is resolved from the running container, not from the tag,
because a tag moves while an old container keeps serving. It is null when the Installer is not
running in a container or the image has no registry digest.
curl -s "http://localhost:${NEST_PORT:-8000}/api/version" \
-H "Authorization: Bearer <token>"GET /api/deployment/status (authenticated) is the Installer's own view of the deployment, in two
parts.
prerequisites — the deployment files the Installer needs:
| Field | Meaning |
|---|---|
envFile.exists | The generated .env is present |
envFile.lineCount | Non-empty lines in it |
composeFile.exists | The downloaded DataMind OS docker-compose.yml is present |
allReady | Both files exist |
containers — the DataMind OS containers, selected by the label
com.docker.compose.project=unistream:
| Field | Meaning |
|---|---|
total, running, stopped | Counts |
conditions | A tally per condition, below |
items[] | Per container: service, containerName, lifecycle, condition, state, status, exitCode, error, restartCount, startedAt, uptimeSeconds |
Container conditions:
| Condition | Meaning |
|---|---|
UP | Running, healthy or no healthcheck defined |
STARTING | Running, healthcheck still in its start period |
UNHEALTHY | Running, healthcheck reporting unhealthy |
FLAPPING | Restarting repeatedly |
DOWN | Created but not started, or exited cleanly (exit 0, or 143/137 without an OOM kill) |
FAILED | Dead, or exited non-cleanly (for example OOM-killed) |
IN_PROGRESS | A one-shot init container still running |
COMPLETED_OK | A one-shot init container that exited 0 |
UNKNOWN | Anything else |
Services with no healthcheck cannot be judged by --wait. For those, the Installer re-checks
5 seconds after recreation and fails the job if the container is DOWN or FLAPPING.
GET /api/health; treat a non-200 as the Installer being down.docker ps and the container healthcheck give the same
liveness signal Docker itself uses.GET /api/deployment/status. That is the Installer's only monitoring view of them.| # | Check | Command | Expected |
|---|---|---|---|
| 1 | Backend answers | curl -s http://localhost:${NEST_PORT:-8000}/api/health | {"status":"ok","db":"up"} |
| 2 | Installer containers running | docker ps --filter name=delamain- | delamain-backend and delamain-postgres up |
| 3 | Database healthy | docker inspect --format '{{.State.Health.Status}}' delamain-postgres | healthy |
| 4 | Migrations finished | docker inspect --format '{{.State.ExitCode}}' delamain-backend-init | 0 |
| 5 | Build recorded | GET /api/version | non-null digest |
| 6 | Deployment files present | GET /api/deployment/status | prerequisites.allReady: true |
| 7 | No failing services | GET /api/deployment/status | conditions has no FAILED, UNHEALTHY or FLAPPING |
| 8 | No update stuck | GET /api/system/self-update-check | lastUpdate.status is completed or null, never left at started |
| 9 | DataMind OS containers up | docker ps --filter label=com.docker.compose.project=unistream | The stack's services are up |
If several checks fail together, start with Troubleshooting and collect the output listed in Logs.