Appearance
Deploying an Instance
A Medipal instance is a self-contained deployment serving one organisation. Partners who host Medipal for their customers deploy and operate instances on their own Kubernetes infrastructure using the charts, images and tooling provided by Medipal.
Requirements
| Requirement | Detail |
|---|---|
| Kubernetes cluster | A current Kubernetes release with a Gateway API or Ingress controller and persistent storage. |
| Container registry access | Credentials for Medipal's private registry, which hosts the images and Helm charts. Provided at onboarding. |
| DNS and TLS | Two hostnames per instance (web application and API), covered by a wildcard certificate or one certificate per host. |
| Outbound email | An SMTP relay for transactional email (invitations, password resets, notifications). |
| Operator tooling | kubectl, helm and the Medipal provisioning CLI installed on the operator's workstation, with a kubeconfig for the cluster. |
| Optional: single sign-on | An Azure AD / Microsoft Entra application registration if the organisation signs in with SSO. |
| Optional: EHR | Network access from the cluster to the organisation's FHIR server. See EHR Connectors. |
What gets deployed
Each instance lives in its own namespace and consists of:
| Component | Role |
|---|---|
| API server | The Medipal backend. On start-up it waits for the database, applies schema migrations, seeds reference data and registers plugins before serving traffic. |
| Web application | The clinician and administrator interface, served behind the instance's web hostname. |
| Database | A PostgreSQL database dedicated to the instance, deployed in the namespace or provided externally. |
| Routes | Gateway API routes (or Ingress rules) mapping the two hostnames to the web application and the API. |
Cluster-wide, one shared namespace holds settings common to every instance (registry pull credentials, SMTP settings) and, optionally, a synthetic FHIR test server used by evaluation instances.
The provisioning CLI
The provisioning CLI wraps kubectl and helm so that day-to-day operation does not require hand-written manifests. It creates and manages instances by a short name; the name becomes part of both hostnames.
| Command | Purpose |
|---|---|
bootstrap | One-time cluster setup: shared namespace, shared settings, registry credentials. |
provision | Create a new instance from scratch: namespace, secrets, database, charts, routes, first administrator. |
status | Readiness of the instance's pods and routes, plus a live health probe of the API. |
list | All instances managed on the cluster. |
secret | Re-display the first-login information for an instance. |
upgrade | Roll the API server and/or the web application to new versions, keeping configuration. |
set | Change one or more runtime settings; the affected component is restarted automatically. |
restart | Restart the instance's components without changing anything. |
destroy | Remove the instance, its namespace and, optionally, its registration with the tracker. |
Every command accepts a kubeconfig option and can print machine-readable output for automation.
Configuration
Configuration is provided per instance and falls into these categories. The CLI generates what can be generated and asks for the rest.
| Category | Examples | Source |
|---|---|---|
| Cryptographic material | Token signing key, encryption key for the Vault, service API key | Generated at provisioning |
| Database | Host, name, credentials | Generated or supplied |
| Addresses | Web and API hostnames, cluster domain | Derived from the instance name |
| SMTP relay, sender name and address | Shared cluster settings | |
| Single sign-on | Azure AD tenant and client identifiers | Supplied per instance |
| Feature flags | Analytics, EHR, workflows, anonymous questionnaires, engine builder, AI tools | Off by default; enabled per instance |
| AI assistant | Provider and model selection, provider credentials | Supplied if AI tools are on |
| First administrator | Email and initial password | Generated at provisioning |
Sensitive values are stored as Kubernetes secrets; non-sensitive values as configuration maps. The set command routes each key to the right place.
Configuration as code
Beyond runtime settings, an instance's content configuration (folders, roles, plugin instances, workflows, consent documents) can be described in a declarative file and applied with the API server's configuration commands: validate checks the file, plan shows what would change, apply makes the changes, and sync exports the current state. This is how partners reproduce a standard set-up across many instances and keep it under version control.
Provisioning walkthrough
- Run
bootstraponce per cluster with the shared settings. - Run
provision <name>with the environment type and, if used, the SSO identifiers. The command creates everything and prints the first-login details once. - Open the web hostname and sign in as the first administrator. Change the password.
- Create folders, roles and users, or apply a configuration-as-code file.
- Enable the feature flags the organisation needs with
set. - If applicable, register the organisation's EHR (see EHR Connectors).
Upgrades
Releases of the API server and the web application are versioned independently. To upgrade, run upgrade <name> with the new version tags. Schema migrations run automatically before the new API server accepts traffic, and the previous configuration is preserved. Test upgrades on a staging instance first; instances of different versions can coexist on one cluster.
Backups and restore
The partner is responsible for backing up each instance's database and for the Vault encryption key, which is required to read secrets in a restored database. Restoring an instance means restoring the database and re-applying the same secrets; the charts and images are stateless.
Health
The API server exposes a health endpoint used by the cluster's readiness checks and by status. The web application is healthy when it serves its start page. Both hostnames should be monitored externally.
Troubleshooting
| Symptom | Likely cause | What to do |
|---|---|---|
| Pods stay in image pull errors | Registry credentials missing in the namespace | Re-run bootstrap or check that the pull secret exists in the instance namespace. |
| API pod does not become ready | Migration or seeding step failed | Read the logs of the API pod's start-up steps; fix the database connection or credentials and restart. |
| Web hostname returns 404 | Route not yet accepted by the gateway | Wait briefly and check the route's status in the namespace. |
| First login fails | Seeding has not completed or the password was mistyped | Run secret <name> to re-display the credentials once the API pod is ready. |
| Email is not sent | SMTP settings incorrect | Update the SMTP keys with set; the API server restarts automatically. |
| SSO login fails | Redirect URIs not registered on the identity provider | Register the web hostname's callback and logout addresses on the application registration. |