kastoria-ohif
The OHIF web-based DICOM viewer, built locally from the
upstream OHIF/Viewers submodule and served by an unprivileged NGINX. The
viewer is designed to sit behind a kastoria-proxy and/or
an kastoria-proxy-mtls reverse proxy as the catch-all
/ route, retrieving pixel data from kastoria-health via
DICOMweb (QIDO-RS/WADO-RS). This viewer also provides support for automatically
handling JWT authorization for redirects from the
kastoria-smart-launch-api container app,
picking up its study context and (optional) viewer JWT from the
URL fragment.
Runtime details
| Property | Value |
|---|---|
| Build stage | node:24-alpine (pnpm run build of the OHIF/Viewers submodule, pinned to v3.13) |
| Runtime base image | nginxinc/nginx-unprivileged:1.31-alpine (pinned by digest) |
| Exposed port | 8080 |
| Container user | nginx (non-root) |
| Entrypoint | /usr/src/entrypoint.sh (injects branding CSS, renders app-config.js from its template, then execs NGINX) |
| Command | CMD ["nginx", "-g", "daemon off;"] |
| Health check | GET http://localhost:8080/ (every 30s, 5s timeout, 30s start period, 3 retries) |
| Stop signal | SIGTERM |
The viewer is a static SPA. Branding (logo, name, version, header URL) and study-list visibility are baked into the bundle at image build time; only the DICOMweb endpoint is resolved by the entrypoint at container startup (see Environment variables below).
OCI labels
| Label | Value |
|---|---|
org.opencontainers.image.title |
OHIF Viewer |
org.opencontainers.image.description |
OHIF medical image viewer |
org.opencontainers.image.licenses |
MIT |
org.opencontainers.image.url |
https://github.com/OHIF/Viewers |
org.opencontainers.image.documentation |
https://docs.ohif.org/ |
io.kastoria.health-endpoint |
/ |
Unlike the other Kastoria-authored images, this image packages the upstream
OHIF Viewers project, so its labels point at the OHIF project itself and its
license is MIT rather than Proprietary.
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-ohif:<release-tag>
notation verify acrmerkalisdist0c66.azurecr.io/<customer>/kastoria-ohif:<release-tag>
See the Distribution Registry guide for authentication and trust setup.
Environment variables
| Variable | Secret | Required | Default | Description |
|---|---|---|---|---|
DICOMWEB_URL[1] |
No | Yes | — | Base URL of the DICOMweb server the viewer queries, e.g. https://dicomweb.example.com. Set to same-origin to use the viewer's own origin. Startup fails if unset. |
PUBLIC_URL |
No | No | / |
Public URL path prefix the viewer is served under. |
PORT[2] |
No | No | 8080 |
HTTP port; also used by the container HEALTHCHECK. |
APP_CONFIG |
No | No | — | Inline app-config.js content that replaces the generated config entirely. |
The entrypoint substitutes DICOMWEB_URL into the built-in app-config.js at
container start; it does not rebuild the image.
Deploying to an Azure Container Apps Environment
[1] DICOMWEB_URL is resolved by the user's browser, not by the container, so it must be a publicly reachable URL. When the viewer is served behind the reverse proxy on the same host, set it to same-origin (or the proxy's public URL) so DICOMweb requests are routed through the proxy to kastoria-health.
[2] The selected value for PORT must match the environment's ingress Target port for the container app.
Build arguments
Branding and a handful of viewer defaults are fixed when the image is built and are not configurable at container runtime:
| Argument | Default | Description |
|---|---|---|
BRAND_NAME |
Merkalis |
Short brand name shown in the header next to the logo. |
BRAND_VIEWER_NAME |
Merkalis Viewer |
Full viewer name shown in the About box and browser tab. |
BRAND_VIEWER_VERSION |
3.13.0 |
Viewer version shown in the About box and browser tab. |
BRAND_VIEWER_URL |
https://merkalis.io |
URL shown in the About box. |
BRAND_ASSETS |
merkalis |
Branding subdirectory to copy logo.png/branding.css from. |
SHOW_STUDY_LIST |
true |
Set to false to hide the study list on startup. |
LOCATION |
deploy |
NGINX server block: deploy serves static files only; local also proxies /studies, /wado. |
The Kastoria distribution builds with LOCATION=deploy, since
kastoria-proxy (or kastoria-proxy-mtls) handles DICOMweb routing.
Available versions
v0.10.0v0.9.1— deprecated for security reasons (CVE-2026-93990); usev0.10.0