kastoria-health
A DICOMweb server that serves STOW-RS ingestion, QIDO-RS queries, and WADO-RS
retrieval over the studies stored in kastoria-storage. The server backs the
kastoria-proxy reverse proxy's /studies path and is the
viewer's source of pixel data.
Runtime details
| Property | Value |
|---|---|
| Runtime base image | kastoria-core (final stage), itself node:24-alpine |
| Exposed port | 3000 |
| Container user | node (non-root) |
| Entrypoint | node --import /app/dicomweb/src/instrumentation.js /app/dicomweb/src/server.js |
| Health check | GET http://localhost:3000/health (every 30s, 5s timeout, 30s start period, 3 retries) |
| Stop signal | SIGTERM |
node_modules for npm/npx are stripped from the runtime image.
OCI labels
| Label | Value |
|---|---|
org.opencontainers.image.title |
Kastoria Health DICOMweb Server |
org.opencontainers.image.description |
DICOMweb server for the Kastoria Health platform |
org.opencontainers.image.licenses |
Proprietary |
org.opencontainers.image.url |
https://github.com/merkalis-io/kastoria-health |
org.opencontainers.image.documentation |
https://github.com/merkalis-io/kastoria-health |
io.kastoria.health-endpoint |
/health |
The org.opencontainers.image.version, org.opencontainers.image.revision,
org.opencontainers.image.created, org.opencontainers.image.source,
io.kastoria.base-image, and io.kastoria.service labels are injected at
build time by the CI/CD pipeline.
Pull and verify
Promoted images are published to the Distribution Registry under the customer namespace:
docker pull acrmerkalisdist0c66.azurecr.io/<customer>/kastoria-health:<release-tag>
notation verify acrmerkalisdist0c66.azurecr.io/<customer>/kastoria-health:<release-tag>
See the Distribution Registry guide for authentication and trust setup.
Environment variables
| Variable | Secret | Required | Default | Description |
|---|---|---|---|---|
NODE_ENV |
No | Yes | production |
Environment; startup fails if unset. |
HOST |
No | Yes | 0.0.0.0 |
not used. |
PORT[1] |
No | No | 3000 |
HTTP port. |
DICOMWEB_URL |
No | No | — | Public base URL of this service. Used for STOW-RS RetrieveURL values; every non-loopback deployment should set it. |
KASTORIA_CONFIG_JSON[2] |
Yes | one of these | — | Storage configuration as an inline JSON string. |
KASTORIA_CONFIG_FILE[2] |
No | one of these | — | Path to a storage configuration JSON file. |
SHUTDOWN_HARD_TIMEOUT_MS |
No | No | 30000 |
Hard deadline in ms for graceful shutdown. |
QIDO_MAX_INDEX_ENTRIES |
No | No | 25000 |
Index entries a multi-attribute QIDO search may read before it reports how far back it reached. |
QIDO_CANDIDATE_CONCURRENCY |
No | No | 20 |
How many candidate studies a QIDO search loads at once. |
WADO_MAX_FRAMES |
No | No | unset | Most frames one /rendered or /thumbnail request may name; a request naming more is refused with 400. Unset or 0 is uncapped. |
JWT_VERIFYING_KEY[3,4] |
Yes | No | feature off | RS256 PEM public key used to verify JWT auth tokens. Setting it turns on per-study viewer-token verification. |
JWT_ISSUER[4] |
No | No | kastoria-smart-launch |
Expected iss claim when verification is on. |
JWT_AUDIENCE[4] |
No | No | kastoria-health |
Expected aud claim when verification is on. |
LRU_NUMBER_OF_ITEMS |
No | No | 1000 |
Maximum entries per in-process LRU cache (four caches each apply this limit). |
LRU_MAX_SIZE_BYTES |
No | No | 2000000000 |
Maximum total bytes per LRU cache. |
LRU_TTL_MS |
No | No | 432000000 |
LRU entry time-to-live in ms. |
STUDY_TTL_MS |
No | No | 10000 |
TTL in ms for the DICOMProcessed study-root CID cache. |
OTEL_ENABLED[5] |
No | No | false |
Set to true to enable OpenTelemetry export. |
OTEL_EXPORTER_OTLP_ENDPOINT[5] |
No | No | — | OTLP collector endpoint, e.g. http://otel-gateway:4317. |
OTEL_DEBUG[5] |
No | No | — | Set to true for verbose OTel diagnostic logging. |
Deploying to an Azure Container Apps Environment
[1] The selected value for PORT must match the environment's ingress Target port for the container app.
[2] At least one of KASTORIA_CONFIG_JSON / KASTORIA_CONFIG_FILE is required for storage initialization. If both are set the value of KASTORIA_CONFIG_JSON is used. See Configuration for the document's contents.
[3] If JWT_VERIFYING_KEY is not set (or set to an empty string), JWT verification (JWT Authorization) is disabled. Note: JWT verification
only covers the QIDO-RS and WADO-RS read routes.
[4] If enabled, incoming JWT tokens presented via the Authorization: Bearer <jwt-token>
header are verified using JWT_VERIFYING_KEY. A valid token will have an
iss that matches JWT_ISSUER, and aud that matches JWT_AUDIENCE.
Both exp and nbf are enforced if provided.
[5] If OTEL_ENABLED is not explicitly set to true, OpenTelemetry metric/trace/logging is disabled.
Available versions
v0.10.0v0.9.1— deprecated for security reasons (CVE-2026-101916); usev0.10.0