Skip to content

Latest commit

 

History

History
256 lines (189 loc) · 8.2 KB

File metadata and controls

256 lines (189 loc) · 8.2 KB

Setup Guide

Vor dem ersten öffentlichen Betrieb (Compliance-Checkliste)

Folgende Punkte müssen vor dem Betrieb mit mehreren Nutzern erledigt sein:

  • Impressum-Platzhalter in api/src/templates/imprint.html befüllen (§ 5 TMG / Art. 10 ECRL)
  • Datenschutzerklärung unter /privacy auf Vollständigkeit prüfen (DSGVO Art. 13/14)
  • DPIA (docs/dpia.md) ausfüllen, unterzeichnen und archivieren (DSGVO Art. 35)
  • PRIVACY_POLICY_VERSION in env/.env.api setzen (für Consent-Versionierung)
  • Festplattenverschlüsselung auf dem Server aktivieren (TOM gem. DSGVO Art. 32)
  • Backup-Verschlüsselung prüfen: env/.env.backupAGE_RECIPIENT gesetzt (age Public-Key)
  • E-Mail-Verifikation getestet (Resend API-Key in env/.env.api)

Requirements

  • Docker + Docker Compose
  • make
  • A Garmin Connect account
  • homelab-gateway running (optional, for homelab proxy setup)

Public SaaS (no homelab-gateway): Use make up-public — bundles Caddy with automatic Let's Encrypt on a public domain. Full runbook: deployment-public.md.


1. Clone and configure

git clone https://github.com/gerfru/PulseBase.git
cd PulseBase
cp env/.env.example env/.env
cp env/.env.app.example env/.env.app
cp env/.env.api.example env/.env.api
cp env/.env.sync.example env/.env.sync
cp env/.env.ml.example env/.env.ml

Edit env/.env (DB-Admin, nur für Flyway/DB-Service):

DB_USER=garmin
DB_PASSWORD=<strong password>
HOST_IP=your-domain.com

Edit env/.env.app (Shared App-Credentials für api + sync-service + ml-service):

DB_APP_USER=garmin_app
DB_APP_PASSWORD=<strong password>
DB_SYNC_USER=pulse_sync
DB_SYNC_PASSWORD=<strong password>   # from make gen-secrets
DB_ML_USER=pulse_ml
DB_ML_PASSWORD=<strong password>     # from make gen-secrets
FERNET_KEY=<from make gen-secrets>

Each app service uses its own least-privilege DB role (V24): api → DB_APP_*, sync-service → DB_SYNC_*, ml-service → DB_ML_*. All six values live in env/.env.app because they feed both the Flyway role-creation placeholders and the service containers.

Edit env/.env.sync:

SYNC_INTERVAL_HOURS=2   # poll Garmin every X hours (default: 2)
SYNC_LOOKBACK_DAYS=30
SYNC_DAILY_DAYS=2

Edit env/.env.ml:

ML_INFER_HOUR=7   # hour (UTC) for daily ML inference; training runs Sunday 3:00

2. Generate secrets

make gen-secrets

Copy the output values:

  • SESSION_SECRETenv/.env.api (min. 32 characters, required)
  • FERNET_KEYenv/.env.app (used by all 3 app services for token encryption)
  • DB_APP_PASSWORD, DB_SYNC_PASSWORD, DB_ML_PASSWORDenv/.env.app (per-service DB role passwords, V24)

Optional — backups: make gen-secrets also prints an age-keygen hint. To enable the encrypted backup container, generate an age keypair on a trusted offsite machine (age-keygen -o pulsebase-backup.key), put the age1… public key as AGE_RECIPIENT in env/.env.backup (cp env/.env.backup.example env/.env.backup), and keep the private key offsite. See deployment-public.md.


3. Start services

make up

This builds the images, runs Flyway migrations, and starts all containers. The API container joins the external proxy network shared with homelab-gateway's Caddy.

Wait until the API is ready:

make status
make logs-dashboard

Public SaaS (without homelab-gateway): Use make up-public instead. This bundles Caddy with automatic Let's Encrypt — open https://<your-public-domain>. Full runbook: deployment-public.md.


4. Register your account

Open https://your-domain.com/register in a browser.

Caddy (via homelab-gateway in home mode, or the bundled Caddy in make up-public) provides the valid TLS certificate via ACME/Let's Encrypt. See docs/deployment-public.md for the public setup.

Create your account with name, email, and password (min. 12 characters). Check all three consent checkboxes (required):

  • Health data processing (DSGVO Art. 9)
  • Terms of Service
  • Age confirmation ≥ 16 years (DSGVO Art. 8)

5. Verify your email

After registering you are redirected to /login?verify=sent (or /login?verify=failed if the email service is not configured).

If RESEND_API_KEY is set: Check your inbox and click the verification link.

If RESEND_API_KEY is not set (local/homelab): The token is printed to the API log. Copy the token from make logs-dashboard and open:

https://your-domain.com/auth/verify/<token>

If the link expires (24h TTL) or never arrived, use /auth/resend-verify to request a new one.


6. Link Garmin

Go to https://your-domain.com/garmin/link (or click the link on the dashboard).

Enter your Garmin Connect email and password. The password is used once to fetch a session token and then deleted from memory — it is never stored anywhere.


7. First sync

After linking Garmin, a sync starts automatically within 1 minute (the link sets sync_requested = true, the sync-service polls for it every minute). Watch progress:

make logs-sync

After sync completes, go to https://your-domain.com/dashboard.


Day-to-day

The sync-service polls Garmin every SYNC_INTERVAL_HOURS (default: 2 hours). No manual action needed after initial setup.


Commands

Command What it does
make up Build images and start all services (requires homelab-gateway proxy network)
make up-public Build and start a public instance with bundled Caddy + Let's Encrypt
make down Stop all services
make reset Stop + wipe all data + re-run migrations (deletes all users!)
make migrate Run pending Flyway migrations
make trigger-sync Request immediate Garmin sync for all users (no rebuild, processed within 1 min)
make sync Rebuild sync-service + restart (triggers full backfill sync)
make dashboard Rebuild and restart the API/dashboard container
make analytics Rebuild and restart the ML analytics service
make logs-dashboard Live logs from the API
make logs-sync Live logs from the sync-service
make logs-analytics Live logs from the ML analytics service
make status Show container status
make db Open a psql shell on the database
make gen-secrets Generate SESSION_SECRET, FERNET_KEY, DB passwords + age-keygen hint
make secure-env Set chmod 600 on all env files
make backup Run an encrypted DB backup now (one-off; otherwise daily via the backup container)
make restore-test Decrypt + TimescaleDB-correct restore of the latest backup into a throwaway DB (key path from AGE_IDENTITY in env/.env.backup)

Adding a second user

  1. Open https://your-domain.com/register in a browser (or incognito window)
  2. Register the new account
  3. Verify the email (see Step 5 above)
  4. Log in and go to /garmin/link
  5. Link the second Garmin account

The sync-service picks up all users with garmin_linked = true from the database automatically on the next run.


Troubleshooting

API won't start / migrations fail: Check that the db container is healthy before the API starts.

make status
make logs-dashboard

proxy network not found: homelab-gateway must be running before make up. Start it first:

cd ../homelab-gateway && make up

Garmin link fails:

  • Check credentials (try logging into connect.garmin.com in a browser)
  • Garmin sometimes requires 2FA — if so, the initial link may time out

Dashboard shows no data after sync:

make logs-sync   # look for errors
make db          # then: SELECT count(*) FROM activities WHERE user_id = 1;

Account locked after failed logins: After 5 failed attempts the account is locked for 15 minutes (auto-unlock). To unlock immediately:

make db

Then in psql:

UPDATE users SET failed_login_attempts = 0, locked_until = NULL WHERE email = 'your@email.com';

Reset everything (nuclear option):

make reset

This wipes the database and all tokens. All users must re-register and re-link.