Your server, your health database
The reference backend the PulsHealth app syncs to. It runs on a home machine, a NAS, or a rented box. There is no hosted option and no managed tier.
Setup
You need a Linux or macOS box with Docker and its Compose plugin. The bootstrap script generates every secret, starts the stack, waits for ingest to answer, and prints a pairing block: the URL the phone should use, the bearer token, the user ID, and a QR code encoding all three.
git clone https://github.com/PulsHealth/pulshealth.git
cd pulshealth
scripts/bootstrap.sh --time-zone Europe/BerlinPass the time zone your phone lives in, since every daily view buckets by that calendar. Re-running the script is safe; it never regenerates secrets.
The script pulls the published images from GHCR. Add --build to compile them from the checkout instead, for example to run an unreleased change.
What comes up
Six services plus a one-shot migrator, all in the same repository as the app, all yours to inspect and change.
How the phone reaches it
Everything binds to loopback by default, including ingest, the product API, the MCP server, Grafana, the viewer and Postgres. How the phone reaches ingest is up to you.
Same Wi-Fi
Bind ingest to the LAN and the pairing block carries a local address; the app accepts plain HTTP for local-network hosts. That is plaintext with the token as the only protection, so use it only on a network you control.
From Anywhere
Put a TLS-terminating proxy or a VPN such as Tailscale in front of the ingest port and hand the script its URL. Ingest stays on loopback and the QR code carries the HTTPS address.
Backups Are Yours
A backup service ships with the stack, but it is an opt-in Compose profile and off until you turn it on. Until then the Postgres volume is the only copy of your data.
Security is your job too
The database holds identifiable health data. Each phone can have its own bearer token, bound to one user, stored only as a hash and revocable on its own. The shared token a new install starts with still works until you switch it off, and anyone who has that one can upload and delete for any user on the server. TLS, network exposure and retention are yours to set up. The security policy lists the known limitations.