Skip to content

Install

From an empty Docker host to a working coachd: Garmin data in, an agent connected, and your passkey enrolled. Just looking? Try it with demo data first, without a Garmin key.

deploy/compose.yaml runs coachd with Tailscale (the private lane), Grafana Alloy, VictoriaMetrics and VictoriaLogs. coachd publishes one port, its public listener on 127.0.0.1:8080: a Cloudflare Tunnel (cloudflared on the host) or a reverse proxy on the host forwards your hostname to it. Run every command in these pages from deploy/.

Get the stack files

git clone https://github.com/stefiix92/coachd.git
cd coachd/deploy
cp .env.example .env

Set COACHD_TIMEZONE in .env. Tokens never go in .env: they are secret files. Every setting is in the configuration reference.

Encrypt the data disk

The coachd-data volume holds health data, raw Garmin JSON and FIT files, and token hashes. It must be on an encrypted disk: put Docker’s data root (or just this volume) on LUKS. coachd does not manage disk encryption.

Get the image

The signed release image, or your own build: Get the image.

Create the secrets

The Garmin key, the Tailscale auth key and the ntfy token: Secrets.

Add your Garmin key

Garmin key.

Open the public lane

Pick one:

  • Cloudflare Access: Cloudflare does the login and MFA, and signs in the AI apps.
  • Built-in auth: coachd does it with your passkey and its own OAuth 2.1 server. No Cloudflare account needed.

Open the private lane

Tailscale, for agents on your own devices.

Enrol your passkey

Enrol a passkey. It approves every workout.

Connect an agent

Claude, ChatGPT or a local client.

Optional extras

Last updated on