Releasesv0.1.0

Docker Compose

The published image and a pinned TimescaleDB, in one command.

The compose file in deploy/docker-compose.yml runs two containers: postgres (TimescaleDB, pinned by its multi-arch digest) and ohs (the published image). It needs Docker Compose v2.24 or later and openssl. Run every command from the repository root.

Configure

git clone https://github.com/soma-intelligence/open-health-sync.git && cd open-health-sync
cp .env.example .env
sed -i.bak "s|^OHS_ENCRYPTION_KEY=.*|OHS_ENCRYPTION_KEY=$(openssl rand -base64 32)|" .env

OHS_ENCRYPTION_KEY must hold 32 random bytes in base64. It encrypts the OAuth tokens stored in the database: keep it with your backups.

Start and check

docker compose --env-file .env -f deploy/docker-compose.yml up -d --wait
docker compose --env-file .env -f deploy/docker-compose.yml run --rm ohs doctor

The ohs container runs ohs up: pending migrations, then the server. Its healthcheck is ohs doctor --quick (database and raw store).

Create a tenant

docker compose --env-file .env -f deploy/docker-compose.yml exec ohs /ohs admin tenant create --name dev

The key is printed once. Continue with the quickstart to upload and read data.

No wearable account yet? ohs seed --demo fills the instance with 90 days of synthetic data from six sources and prints a key, a user and calls to try. See Try it without a wearable.

docker compose --env-file .env -f deploy/docker-compose.yml exec ohs /ohs seed --demo

Keep --env-file .env on every command

Compose reads ${...} variables (OHS_VERSION, OHS_HTTP_PORT, OHS_HTTP_BIND, POSTGRES_PASSWORD, S3_*) from the shell or --env-file, not from the repository root. The containers read .env themselves either way.

Port and a second install

The API is published on host port 8080 of 127.0.0.1, so only this machine reaches it. Other machines go through a reverse proxy with TLS, or set OHS_HTTP_BIND=0.0.0.0 in .env to publish plain http on every interface. To use another port, set both in .env:

.env
OHS_HTTP_PORT=8081
OHS_PUBLIC_URL=http://localhost:8081

ohs doctor cannot tell when they disagree, and OAuth callbacks use OHS_PUBLIC_URL.

The compose project is named ohs, which also names its containers and volumes. A second install on the same host needs its own project name and its own port, or it takes over the first one's containers and data. Run it from its own checkout, with its own .env, and pass the project name on every command:

docker compose -p ohs-test --env-file .env -f deploy/docker-compose.yml up -d --wait

Images and architectures

Each release publishes ghcr.io/soma-intelligence/open-health-sync for linux/amd64 and linux/arm64, tagged with the version and edge. The image is distroless (static, nonroot). The compose file uses ${OHS_VERSION:-<current release>}: set OHS_VERSION in .env to pin another release.

Where the data lives

VolumeHolds
pgdataPostgres: tenants, users, connections, jobs and every normalized record
rawthe raw store: every payload, verbatim

docker compose ... down keeps both. down -v deletes them, with everything in them. Back them up together with .env: see Backup and restore.

Edit on GitHub

On this page