Skip to content

Technical documentation

Installing the platform

What an installation of the HealthDati platform needs, and how to set up the centre and a clinic. The commands refer to the platform's repository, which also holds the detailed guides.

Overview

An installation has two sides, as the architecture page shows:

SideWhat runs there
Centrethe central service with its database, and the Train a model interface
Clinicthe clinic node with worker, trainer, inference service, model sync and dataset catalogue, and the Assess risk interface

The clinic opens every connection itself: the worker and the model sync connect to the central service, and the centre never calls into the clinic. Both sides can also run within the same institution.

Project members receive the source code. Every image is built from it; the paths on this page refer to the repository.

Requirements

  • Docker Engine 24 or later with Docker Compose v2.
  • Processors are enough; no graphics card is needed. In the clinic's reference stack, the trainer is limited to 2 processor cores and 2 GB of memory.
  • A few gigabytes of disk space for the images, and internet access while building: the builds fetch pinned base images and packages.
  • For the centre's installation script, Python and openssl on the host.
  • For the multi-site installation, a Bash shell; on Windows, Git Bash.
  • To build without Docker, Node.js 24 or later and Python 3.10 or later.

The services and their connections:

PortServiceWho connects
8794central servicethe worker and model sync of each clinic, outbound from the clinic
8080Train a modelbrowsers at the centre
8081Assess riskbrowsers on the clinic's network
8795inference serviceonly Assess risk in the same clinic

The platform needs no connection into the clinic. Restrict access to both interfaces through the institution's network.

Trying it out

The interfaces in demo mode

In the directory platform/software/frontend, with the two uvicorn commands in separate terminals:

cd web
npm ci
npm run build
cd ..
pip install -r requirements-demo.txt
HDP_DEMO=1 uvicorn app.main:app --port 8080
HDP_DEMO=1 uvicorn inference_app.main:app --port 8081

With Docker, no local packages are needed; one Dockerfile builds both interfaces:

docker build --target training -t hdp-training .
docker run --rm -p 8080:8080 -e HDP_DEMO=1 hdp-training
docker build --target inference -t hdp-inference .
docker run --rm -p 8081:8081 -e HDP_DEMO=1 hdp-inference

Train a model is then available at http://127.0.0.1:8080, and Assess risk at http://127.0.0.1:8081. The tutorial walks through both.

One centre and three clinics on one computer

In the directory platform/deploy/sites:

./sites.sh build
./sites.sh up
./sites.sh status

build builds the five images; up starts the centre and then clinics A, B and C, each on its own sealed network. Each clinic registers a dataset in its catalogue at start-up and fetches its model from the centre.

AddressWhat runs there
http://127.0.0.1:8080Train a model
http://127.0.0.1:8794/docsthe central service's interfaces
http://127.0.0.1:8181, :8182, :8183Assess risk of clinics A, B and C

./sites.sh logs clinic-a shows a clinic's logs, and ./sites.sh cohort clinic-a evaluates its dataset. ./sites.sh down stops everything; ./sites.sh down -v also removes the database, catalogues and model registries. A further clinic comes from a copy of clinics/clinic-a.env with its own id, port and subnets.

Setting up the centre

The centre's operations package is in platform/software/backend/deploy:

./install.sh
docker compose up -d --build

install.sh writes a .env with a newly generated access token (HDP_API_TOKEN) and database password, without printing either, and sets up the model registry. The package starts the database and the central service; the database migrations run at start-up. The service listens on port 8794 at 127.0.0.1 (BACKEND_BIND). Make it available to the clinics through a TLS reverse proxy.

Build the Train a model interface in platform/software/frontend and connect it to the central service:

docker build --target training -t hdp-training .
docker run -d -p 8080:8080 \
  -e HDP_BACKEND_URL=<address of the central service> \
  -e HDP_BACKEND_TOKEN=<HDP_API_TOKEN from the .env> \
  hdp-training

If the service presents a certificate from your own certificate authority, pass that authority to the interface with HDP_BACKEND_CA_FILE.

The clinics fetch their model from the centre's model registry. Put a model there with node-client registry push --backend-url <address> --job-id <id> --artifact <model file>; the model-publish service in platform/deploy/sites/central/compose.yaml shows the call for the seed model.

Setting up a clinic

Set up the clinic node as a container stack, modelled on platform/deploy/sites/clinic/compose.yaml: worker, trainer, inference service, model sync and the Assess risk interface, with volumes for the dataset catalogue, model registry, exchange files and journal. The trainer runs without a network and on a read-only file system. Start the worker and the trainer together: the worker takes a job only while the trainer is ready.

VariableServiceMeaning
HD_BACKEND_URLworker, model syncaddress of the central service
HD_API_TOKENworker, model syncthe centre's access token (HDP_API_TOKEN from its .env)
HD_CA_FILEworker, model synctrust anchor for the connection to the centre; with it, the node connects over HTTPS only
HD_NODE_NAMEworkerthe node's name
HD_SPOOL_DIR, HD_CATALOGUE_DIR, HD_EGRESS_JOURNAL_DIRworker, trainerdirectories for exchange files, the dataset catalogue and the journal
HDP_REGISTRYinference servicethe clinic's model registry
HDP_INFERENCE_URLAssess riskaddress of the inference service, such as http://inference:8795
HDP_CLINIC_NAMEAssess riskthe clinic's name, as the interface shows it as the location

Data. Data enters the node through the dataset catalogue. node-client dataset register --from <directory> --label <name> --kind site --uses cohort-inference takes an export in the platform's data format, one CSV file per entity, as an immutable snapshot. The catalogue accepts the hospital's data only pseudonymised: the node's data connector writes the export with the key from node-client pseudonym-key init and adds a source-manifest.json. The data owner then approves the snapshot for its purpose with node-client dataset approve.

Model. The model sync fetches the model from the centre and checks it against pinned SHA-256 checksums for the model and its operating point (node-client registry sync). The values for the seed model are in platform/deploy/sites/sites.env.

Checking the installation

  • Centre: curl -s http://127.0.0.1:8794/health reports "status":"ok" and the database as its store. docker compose exec backend python -m app.hdpctl status sums up the state; jobs, nodes and models list jobs, participating nodes and models.
  • Interfaces: /api/health reports for each connected service whether it can be reached.
  • Node: node-client health checks the connection to the centre, node-client registry verify --root <model registry> the model registry, and node-client egress verify the journal of every message that left.
  • First training run: start a job in Train a model. Its status moves from submitted through accepted and running to completed, and the node shown is the clinic that ran it.
  • First assessment: calculate a single case in Assess risk.

Detailed guides

TopicIn the repository
Multi-site installationplatform/deploy/sites/README.md
The centre's operations packageplatform/software/backend/deploy/README-Betrieb.md
Credentials and certificatesplatform/software/backend/docs/credentials-and-enrolment.md
Interfacesplatform/software/frontend/README.md
Clinic node, trainer and egress gateplatform/software/node-client/README.md, docs/training-sandbox.md, docs/export-contract.en.md