Astrea

Products/PhysioSuite

PhysioSuite

By Astrea · AI and Automation Lab of MTH Group · Released 14 November 2026

The physiotherapy platform built for Malaysia.

Overview

Patient records, visits, scheduling, documents and billing in one system, shaped around how Malaysian physiotherapy practices work: MyKad numbers, insurance panels and guarantee letters included.

Two ways to install

PhysioSuite installs in one of two ways: on two servers, an application server and a data server joined by a private network, or on one server that holds both. The same command starts either, and the setup page asks where the data lives.

Two servers

Two servers. Staff reach the application server over HTTPS: its reverse proxy passes them to PhysioSuite's screens and API, and it keeps no records. It talks to the data server over an encrypted private network. The data server holds the database, the documents and the nightly backup, with an off-site copy set up separately. Staff, in a browser HTTPS Application server Reverse proxy PhysioSuite: screens and API encrypted private network Data server Database Documents Nightly backup Off-site copy set up separately

The application server runs PhysioSuite and keeps no records. The data server keeps the records, the documents and their nightly backup: a NAS, a PC or another server. The two talk only over an encrypted private network that PhysioSuite runs itself.

Choose it to keep patient records off the machine that staff reach over the internet.

One server

One server. Staff reach it over HTTPS: its reverse proxy passes them to PhysioSuite's screens and API, and the same machine holds the database, the documents and the nightly backup, with no private network. An off-site copy is set up separately. Staff, in a browser HTTPS One server Reverse proxy PhysioSuite: screens and API same machine, no private network Database Documents Nightly backup Off-site copy set up separately

One machine runs PhysioSuite and keeps the records, the documents and their nightly backup, with no private network to set up and one web address instead of two.

Choose it where the records may be kept on that machine. Set up the off-site copy too: a backup on the same disk does not survive the loss of the server.

Either way, one command on the server that runs PhysioSuite checks this release and starts a one-time setup page, which does the rest.

Requirements

A licence from Astrea

The registry account and the licence key, which let the server download PhysioSuite. Licence enquiries: support@astrealab.ai.

Web addresses

PhysioSuite's own, with a DNS record pointing at the application server. With two servers, a second for their private network, pointing at the same server.

A named first administrator

A person's own sign-in name. Shared names such as admin are refused, as the audit log records who did what.

Later, and not needed to install: off-site storage, any S3-compatible bucket, for an off-site copy of the backups.

The application server

The machine that runs PhysioSuite, wherever the practice chooses to run it. With two servers, it keeps no records.

MinimumRecommended
System64-bit Linux with Docker EngineUbuntu Server 24.04 or 26.04 LTS, or Debian 12 or 13, where the installer can install Docker itself
ProcessorIntel or AMD, 64-bit (x86_64)The same
Cores12
Memory2 GB4 GB
Disk10 GB, with 5 GB free for PhysioSuite20 GB, SSD
DockerDocker Engine 24.0 and Docker Compose 2.20.0 or laterThe versions PhysioSuite is tested on (below)
PortsTCP 80 and 443 from the internet, or your existing reverse proxy (nginx, Apache, Caddy) forwarding to PhysioSuite; UDP 3478The same
AccessSSH, as a user who may use sudoThe same

The data server

The machine that keeps the records and their nightly backup: a NAS with Docker, a PC, a virtual machine or another server, each installed the same way.

MinimumRecommended
System64-bit Linux with Docker EngineA NAS with mirrored or RAID disks, or Ubuntu Server LTS or Debian
ProcessorIntel, AMD or ARM, 64-bit (x86_64 or aarch64)The same
Cores24
Memory4 GB8 GB
Disk10 GB free, plus twice the size of the practice's documents, on the machine's own disks; the database never on a network shareThe same, on mirrored or RAID disks; SSD for the database where there is a choice
DockerDocker Engine 24.0 and Docker Compose 2.20.0 or laterThe same as the application server
PortsNone from the internet. It connects out to the application server on TCP 443 and UDP 3478The same
AccessSSH from the office network, as an administrator who may use sudoThe same
PowerAlways on: never asleep or switched off at night, when the backup runsOn a UPS

Both on one server

Where the records may stay on the application server ("This server" on the setup page), one machine holds both.

MinimumRecommended
ProcessorIntel or AMD, 64-bit (x86_64)The same
Cores24
Memory4 GB8 GB
DiskThe application server's and the data server's togetherThe same, SSD
DockerDocker Engine 24.0 and Docker Compose 2.25.0 or laterThe same
PortsTCP 80 and 443 from the internet, or your existing reverse proxy; no UDP 3478, as there is no private networkThe same

Below the minimum memory or cores, the installer warns and carries on. It refuses less than 5 GB of free disk, and a machine it cannot run on: one that is not Linux or not 64-bit, ARM for the application server, Docker Desktop, Docker installed from Snap, and Podman. A machine that sleeps or is switched off at night, and a database service run by a hosting company, are not supported.

Tested on Ubuntu 26.04 LTS with Docker Engine 29.9.1 and Docker Compose 5.6.0. Where Docker is missing on Debian or Ubuntu, the installer offers to install Docker Engine 29 and Docker Compose 5 from Docker's own repository, never on a NAS. The figures above were measured in Astrea's own tests, with a practice's scale of invented data.

What the installer sets up

For your IT team: each part PhysioSuite runs, on which server, what it does, its image in this release, and what it listens on. Each part runs in its own Docker container, from an image pinned for this release; this table is made from the release's own files.

The reverse proxy: PhysioSuite's own, or yours

PhysioSuite's built-in reverse proxy is Traefik. Where TCP ports 80 and 443 are free on the application server, it takes them: it receives every visit over HTTPS, gets and renews the certificates from Let's Encrypt, and passes each request on to the part that answers it. Where your existing reverse proxy (nginx, Apache, Caddy or Traefik) already holds 80 and 443, PhysioSuite leaves it in charge: the installer prints the settings to add to it, filled in for your server, and Traefik then listens only on two local ports behind it. Your reverse proxy keeps its other sites, and holds the certificates for PhysioSuite's addresses. Either way, UDP 3478 stays open directly, for the private network's relay.

PartWhat it doesImage in v0.1.1Listens on
The application server
Reverse proxy (Traefik)PhysioSuite's built-in reverse proxy. It receives every visit over HTTPS, gets and renews the certificates from Let's Encrypt, sends plain HTTP on to HTTPS, and passes each request to the screens, the API, the setup page while it runs, or Headscale.traefik:v3.7.17TCP 80 and 443 from the internet; UDP 3478 for the private network's relay. Behind your existing reverse proxy: TCP 11000 and 11001 on a local address instead of TCP 80 and 443.
Private network: coordination (Headscale)Decides which machines may join the private network, and relays its traffic when a direct path is blocked. Only PhysioSuite's two servers join.headscale/headscale:v0.29.7No port of its own: reached through the reverse proxy at the private network's address.
Private network: this server's end (Tailscale)The application server's end of the encrypted tunnel (WireGuard) to the data server.tailscale/tailscale:v1.104.4No port on the host: it connects out.
PhysioSuite's APIPhysioSuite's back end (Django). It reaches the database through the private network and keeps no records on this server.physiosuite/backend:v0.1.1No port on the host: reached through the reverse proxy.
PhysioSuite's screensThe pages staff open in their browser, served by nginx.physiosuite/frontend:v0.1.1No port on the host: reached through the reverse proxy.
The setup pageThe one-time setup page, only while the install runs; it is removed when the install finishes.python:3.13.18-slim-trixieNo port on the host: reached through the reverse proxy at /setup while it runs.
The data server
Private network: this server's end (Tailscale)The data server's end of the encrypted tunnel to the application server.tailscale/tailscale:v1.104.4No port on the host: it connects out.
Database (PostgreSQL)Keeps PhysioSuite's records.postgres:18.6-trixieNo port on the host or the office network: only inside the private network.
Nightly database copy (pg_dump)Copies the database every night with pg_dump, from the database's own image, into one file.postgres:18.6-trixieNo port: reaches the database inside the private network.
Backups (restic)Keeps encrypted restore points of the database copy and the documents store, on the data server.restic/restic:0.19.1No network at all.
Both servers
Docker Engine and Docker ComposeRun each part above in its own container. The installer uses the server's own Docker; on Debian or Ubuntu without it, it offers to install Docker's own packages, and installs them only on a clear yes. Never on a NAS.Engine 24.0 and Compose 2.20.0 or later; installed: Engine 29, Compose 5No port.

With one server holding both, the data server's parts run on the application server: the private network is not started, its relay port is not opened, and the database answers on an internal Docker network only. The documents store is a folder, not a program: on the data server, shared to the application server and marked once with sudo physiosuite mark-store.

Install

This page is for PhysioSuite v0.1.1. The newest release is always at get.astrealab.ai/physiosuite/.

On the application server, as a user who may use sudo:

$ curl -fsSL https://get.astrealab.ai/physiosuite/v0.1.1/install.sh -o install.sh
$ sudo bash install.sh

The first line downloads a short script; read it before running it if you wish: install.sh. Another release is installed with sudo bash install.sh --version vX.Y.Z.

What happens next

  1. The script downloads PhysioSuite v0.1.1, checks Astrea's signature and the archive's checksum, and stops if either check fails. Nothing runs before both pass.
  2. It checks the server, chooses PhysioSuite's built-in reverse proxy or finds your existing one, and asks one question: PhysioSuite's web address.
  3. It prints a link and a one-time setup code. Open the link in a browser. The code works for 60 minutes and five tries, in one browser only. Closing the SSH window does not stop the setup: in a new one, sudo physiosuite setup status shows where it is, and sudo physiosuite setup logs -f follows its lines.
  4. The setup page asks the rest in seven steps, each checked before the next: this installation, the reverse proxy, backups, the data server, modules and the first administrator, a review, and the install. With two servers, the data server joins in the fourth step, with one command over SSH, a NAS included.
  5. When the install finishes, the setup page closes and its code is deleted. The first administrator signs in at PhysioSuite's address.

Releases

ReleaseDatePage
v0.1.114 November 2026v0.1.1
v0.1.013 November 2026v0.1.0

What is new in v0.1.1

Added

  • The setup page asks for the receipt's document type (RECEIPT by default) beside the invoice's, and the installer writes it to the application's settings. A self-pay visit's receipt is then left out of the check made before a visit is sent to submissions or invoiced, as the invoice is.

Changed

  • pypdf 7.0.0, which fills AIA's assessment letters (from 6.21.4).
  • The screens' test tools: vitest 5.1.0 and jsdom 31.0.0. Nothing changes on screen.

Fixed

  • Signing a release with no passphrase for the release key now says so in plain words, instead of stopping with gpg's "Inappropriate ioctl for device".

Files of v0.1.1

FileSizeSHA-256
physiosuite-v0.1.1.tar.gz280 KB4890f82762e4435ec65754cb897cba3824ea707d8257a723d29dffe33496d693
install.sh8 KB9904158db406726cfacb565f86ba70e119f2eae45e8fd650ee423ded922a1127
astrea-release-key.asc421 bytesd4882f1e7fe9b46362bf6a2ea7200c72b8078d75f8be9a72c8e024ff37d81276

Verify

The script does this on its own. To repeat it by hand, as Ubuntu's own downloads are checked:

$ v=v0.1.1; base=https://get.astrealab.ai/physiosuite/$v
$ curl -fsSL -O "$base/SHA256SUMS" -O "$base/SHA256SUMS.gpg" \
  -O "$base/physiosuite-$v.tar.gz" -O "$base/astrea-release-key.asc"
$ gpg --show-keys astrea-release-key.asc
$ gpg --dearmor < astrea-release-key.asc > astrea-release.gpg
$ gpgv --keyring ./astrea-release.gpg SHA256SUMS.gpg SHA256SUMS
$ sha256sum --check --ignore-missing SHA256SUMS

The key's fingerprint must read:

2238 0CCB 5687 2AD0 5807 ABC0 1ADA C65F 0D4F 070B

On Debian 13, where gpgv is not installed, use sqv --keyring astrea-release.gpg --signature-file SHA256SUMS.gpg SHA256SUMS instead.