Work through this list after the first deployment has completed and before anybody else is given the address. Each line says how to check it.
Every Installer container is in its expected state. postgres Up (healthy), backend-init
Exited (0), backend Up (healthy):
docker compose -f /opt/delamain/docker-compose.yml ps
The API reports its database as reachable.
curl -sS http://localhost:8000/api/health
Expected: {"status":"ok","db":"up"}. Anything else — or HTTP 503 — means the Installer cannot
serve its own state.
The UI loads from the host address at http://<host>:<NEST_PORT>/ and the login form appears
(the registration form must not appear again).
Every DataMind OS service is running, with no container in a failed state, on the Status screen.
docker compose -f /opt/delamain/deployment/docker-compose.yml ps
The DataMind OS stack's own health checks pass, not just its processes running. Services without a health check cannot be verified by the Installer, and its "apply configuration" step re-checks those services for crash loops instead.
The generated secrets exist in the volume and were not hand-set in .env:
jwt.secret, encr.key, curato.token and pg.pass.
docker volume ls | grep delamain_secrets docker run --rm -v "$(docker volume ls -q | grep delamain_secrets):/s" alpine ls -l /s
The volume is stored as <compose project>_delamain_secrets, and the compose project is the
directory name, so delamain_secrets alone may not be the full volume name.
JWT_SECRET, POSTGRES_PASS, NEST_ENCR_KEY, CURATO_SERVICE_TOKEN and
AZURE_CLIENT_SECRET are not present in .env. They are generated or stored elsewhere.
The administrator password is set by you and not a value anybody else has seen.
The Azure client secret is the one you intend to keep. Replacing it later is possible from the UI, but rotating it invalidates the value the Installer uses for every pull until it is saved again.
delamain_secrets and pgdata are backed up together. Losing the secrets volume breaks the
connection to the database it belongs to and makes stored secrets undecryptable; losing pgdata
loses users, configuration and the audit trail.
A backup exists for each of these, and a restore has been tested at least once:
| What | Where |
|---|---|
| Installer database | The pgdata Docker volume |
| Installer secrets | The delamain_secrets Docker volume |
| Deployment files | /opt/delamain/deployment/ — the generated .env, the compose file, and any docker-compose.override.yml you added |
| Installer configuration | /opt/delamain/.env and /opt/delamain/docker-compose.yml |
| DataMind OS data | The data volumes of the deployed stack |
You know that the Installer has no built-in backup feature. Backups are an operator responsibility; the product does not schedule, store or verify them.
GET /api/health on the host and alerts when it stops returning
{"status":"ok","db":"up"}.postgres and backend use restart: unless-stopped,
so a crash-looping container can look "up" in a casual glance. The Status screen reports each
container's state and health, and GET /api/deployment/status returns the raw state, exit code,
restart count and uptime for every container of the deployed stack.GET /api/deployment/actions returns every
deployment, configuration and migration action ever taken, newest first, with the acting user
resolved. It is the only record of who changed what.user role for anybody who should not hold
admin. Read
Who should have access before adding
anyone. VERSION in /opt/delamain/.env names the build you intend to run. The compose file's
fallback is prod-latest; the shipped .env.example says latest. Confirm the tag resolves to
the intended image, and prefer a fixed tag over a moving one.
docker compose -f /opt/delamain/docker-compose.yml config | grep -m1 image:
The running build is the one you expect. GET /api/version reports the image reference and
the digest of the image the running container is actually executing — it is resolved from the
container, not from the tag, so it cannot drift when a tag is re-pointed.
BLOB_ARTIFACT_VARIANT is unset, so the Installer uses the production environment schema and
compose file rather than the development pair.
Self-update is understood before you use it. It replaces the Installer's compose file with
the published one, so local edits to that file do not survive; the previous file is kept beside
it as docker-compose.yml.pre-update, and the update is the one place where a failed switch
rolls back automatically.
Only NEST_PORT (default 8000) is published by the Installer, and the PostgreSQL port is
not published. Confirm with docker compose -f /opt/delamain/docker-compose.yml ps and your
firewall rules.
SWAGGER_ENABLED is false on the production host, so /api/docs is not served.
TLS is terminated in front of the Installer, because the Installer does not terminate TLS
itself: it serves plain HTTP on NEST_PORT and marks its cookies Secure only when the request
itself is HTTPS or a proxy sets x-forwarded-proto: https. A reverse proxy or load balancer is
what makes the session cookies Secure and keeps credentials off the wire.
NEST_ORIGINS is left alone unless you deliberately point the UI at the API from a different
origin. In the default same-origin setup it is irrelevant.
The DataMind OS stack's own TLS is configured where that deployment expects it. The Installer accepts SSL certificate and key paths as deployment configuration values on the migration path; they configure the stack, not the Installer.
The unistream Docker network is still present and still external to both compose
projects:
docker network inspect unistream --format '{{.Name}}'<USER>
placeholder.Back to the section overview: Getting Started.