generated from eblume/project-template
doc(heph-pwa): production runbook — host the app from the hub (indri) with OIDC
All checks were successful
Build / validate (pull_request) Successful in 6m18s
All checks were successful
Build / validate (pull_request) Successful in 6m18s
Add host-heph-pwa.md: a deployment how-to for serving the PWA from the canonical hub in the hub/spoke OIDC setup (post-release) — fetch the shell at the hub's tag, add --web-root, terminate TLS (tailscale serve / reverse proxy), and the token-paste caveat with the device-code-login follow-up. Cross-linked from heph-pwa and the how-to index. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
271c609c14
commit
936c2635ef
3 changed files with 129 additions and 0 deletions
|
|
@ -112,6 +112,7 @@ Search (🔍 or `/`) runs full-text search across tasks and docs.
|
||||||
|
|
||||||
## Related
|
## Related
|
||||||
|
|
||||||
|
- [[host-heph-pwa]] — serve this app from the hub (indri) with OIDC, in the hub/spoke deployment
|
||||||
- [[set-up-sync-hub]] — stand up the server-mode hub the app talks to
|
- [[set-up-sync-hub]] — stand up the server-mode hub the app talks to
|
||||||
- [[run-the-daemon]] — run `hephd` as a managed service
|
- [[run-the-daemon]] — run `hephd` as a managed service
|
||||||
- [[v1-prototype-tech-spec]] — data model, RPC API, quick-add spec
|
- [[v1-prototype-tech-spec]] — data model, RPC API, quick-add spec
|
||||||
|
|
|
||||||
127
docs/how-to/host-heph-pwa.md
Normal file
127
docs/how-to/host-heph-pwa.md
Normal file
|
|
@ -0,0 +1,127 @@
|
||||||
|
---
|
||||||
|
title: Host heph-pwa from the hub
|
||||||
|
modified: 2026-06-04
|
||||||
|
tags:
|
||||||
|
- how-to
|
||||||
|
---
|
||||||
|
|
||||||
|
# Host heph-pwa from the hub
|
||||||
|
|
||||||
|
How to serve the [[heph-pwa]] mobile app from the canonical **hub** (`indri`) in
|
||||||
|
the hub-and-spoke deployment, with OIDC auth — the production counterpart of the
|
||||||
|
unauthenticated single-machine demo. Assumes the `heph-pwa` work is **merged and
|
||||||
|
released**, so the installed `hephd` already has `--web-root` and CORS.
|
||||||
|
|
||||||
|
> Read [[set-up-sync-hub]] first — this builds directly on the hub it stands up
|
||||||
|
> (server mode, Authentik OIDC, Tailscale transport).
|
||||||
|
|
||||||
|
## What the app needs from the hub
|
||||||
|
|
||||||
|
The PWA is a thin, online-only client: it loads its static shell over HTTP and
|
||||||
|
makes JSON-RPC calls to the hub's `/rpc`. So the hub must (1) serve the shell
|
||||||
|
files and (2) accept the app's authenticated RPC calls. Both are already in
|
||||||
|
`hephd --mode server`:
|
||||||
|
|
||||||
|
- `--web-root <dir>` serves the shell for any non-API path (with an `index.html`
|
||||||
|
SPA fallback). The shell is unauthenticated — it is only HTML/JS; all data
|
||||||
|
still flows through the OIDC-gated `/rpc`.
|
||||||
|
- Every response carries permissive CORS headers and answers the `OPTIONS`
|
||||||
|
preflight, so the shell may instead be hosted anywhere and still call the hub
|
||||||
|
cross-origin.
|
||||||
|
|
||||||
|
## 1. Put the shell on the hub
|
||||||
|
|
||||||
|
The release does not yet bundle the app, so fetch the `heph-pwa/` directory at
|
||||||
|
the **same version tag** the hub runs (keeping shell and hub in lockstep matters
|
||||||
|
— see *Upgrades* below), and copy it to a stable path:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# on indri, matching the running hephd version (e.g. v1.4.0)
|
||||||
|
git clone --depth 1 --branch v1.4.0 \
|
||||||
|
https://forge.ops.eblu.me/eblume/hephaestus.git /tmp/heph-src
|
||||||
|
sudo mkdir -p /var/lib/heph/web
|
||||||
|
sudo cp -r /tmp/heph-src/heph-pwa/. /var/lib/heph/web/
|
||||||
|
```
|
||||||
|
|
||||||
|
> **Future improvement:** have the release workflow package a `heph-pwa-<version>.tar.gz`
|
||||||
|
> asset (as it already does for docs), so this step becomes "download + extract"
|
||||||
|
> and the lockstep is automatic. Until then, pin the clone to the hub's tag.
|
||||||
|
|
||||||
|
## 2. Add `--web-root` to the hub service
|
||||||
|
|
||||||
|
Extend the hub invocation from [[set-up-sync-hub]] with `--web-root` (everything
|
||||||
|
else — issuer, audience, db — unchanged):
|
||||||
|
|
||||||
|
```bash
|
||||||
|
hephd --mode server \
|
||||||
|
--http-addr 0.0.0.0:8787 \
|
||||||
|
--db /var/lib/heph/heph.db \
|
||||||
|
--web-root /var/lib/heph/web \
|
||||||
|
--oidc-issuer https://authentik.ops.eblu.me/application/o/heph/ \
|
||||||
|
--oidc-audience <heph-client-id>
|
||||||
|
```
|
||||||
|
|
||||||
|
In the systemd unit (or launchd plist), add the two `--web-root` arguments and
|
||||||
|
`systemctl restart hephd`. Self-update is compatible now that the release ships
|
||||||
|
the flag — just refresh the web-root on each upgrade (next section).
|
||||||
|
|
||||||
|
## 3. Terminate TLS (recommended)
|
||||||
|
|
||||||
|
Serve the app over **HTTPS** so it is a *secure context*: only then do the
|
||||||
|
service worker (offline launch), proper PWA install, and the Web Speech mic
|
||||||
|
work. (On iOS, "Add to Home Screen" and keyboard dictation work over plain HTTP
|
||||||
|
too, so HTTPS is a polish step, not a blocker.) Two good options:
|
||||||
|
|
||||||
|
- **Tailscale serve** — tailnet-only, automatic MagicDNS cert, no public
|
||||||
|
exposure:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
tailscale serve --bg --https=443 http://127.0.0.1:8787
|
||||||
|
# app is then at https://indri.<tailnet>.ts.net/
|
||||||
|
```
|
||||||
|
|
||||||
|
Bind `hephd` to `127.0.0.1:8787` in this case and let Tailscale be the only
|
||||||
|
thing exposing it.
|
||||||
|
|
||||||
|
- **Reverse proxy** (Caddy / nginx) terminating a real cert, if the hub should
|
||||||
|
be reachable beyond the tailnet. Proxy all paths (`/`, `/rpc`, `/sync/*`) to
|
||||||
|
`hephd`.
|
||||||
|
|
||||||
|
Either way the app is same-origin with the hub, so no CORS is involved and the
|
||||||
|
app defaults its hub URL to its own origin.
|
||||||
|
|
||||||
|
## 4. Connect a phone
|
||||||
|
|
||||||
|
1. Ensure the phone is on the tailnet (or can reach the proxy).
|
||||||
|
2. Open the hub URL (`https://indri.<tailnet>.ts.net/`) and **Add to Home Screen**.
|
||||||
|
3. The app defaults its **Hub URL** to the origin it loaded from — no typing.
|
||||||
|
4. **Token:** the hub requires an OIDC bearer token, and the PWA does **not yet
|
||||||
|
implement the in-app device-code login** — paste a token into Settings →
|
||||||
|
Token for now. Obtain one via the device-code flow against the Authentik
|
||||||
|
client (the same flow the CLI uses; e.g. reuse the access token a logged-in
|
||||||
|
spoke cached, or run a one-off device-code grant). Tap **Test** to confirm.
|
||||||
|
|
||||||
|
> **Known gap / next step:** wire the RFC 8628 device-code flow into the PWA's
|
||||||
|
> Settings so login is in-app (open the verification URL, poll for the token,
|
||||||
|
> store it, and refresh it) — removing the manual paste. Tracked as follow-up
|
||||||
|
> work for `heph-pwa`.
|
||||||
|
|
||||||
|
## Upgrades
|
||||||
|
|
||||||
|
On each hub upgrade, refresh the shell so it matches the running `hephd`:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git -C /tmp/heph-src fetch --depth 1 origin v1.5.0 && git -C /tmp/heph-src checkout v1.5.0
|
||||||
|
sudo cp -r /tmp/heph-src/heph-pwa/. /var/lib/heph/web/
|
||||||
|
```
|
||||||
|
|
||||||
|
The service worker is versioned (`CACHE = "heph-pwa-vN"`), so an updated shell
|
||||||
|
evicts the old cache on next load. Hard-refresh once if a phone seems stuck on a
|
||||||
|
stale version.
|
||||||
|
|
||||||
|
## Related
|
||||||
|
|
||||||
|
- [[heph-pwa]] — the app itself (features, quick-add, voice, triage)
|
||||||
|
- [[set-up-sync-hub]] — stand up the hub + Authentik OIDC this doc extends
|
||||||
|
- [[run-the-daemon]] — run `hephd` as a managed service
|
||||||
|
- [[v1-prototype-tech-spec]] — RPC API and auth model
|
||||||
|
|
@ -22,3 +22,4 @@ Task-oriented guides for common operations.
|
||||||
- [[import-todoist]] — Seed a heph store from your Todoist projects + tasks (`mise run import-todoist`)
|
- [[import-todoist]] — Seed a heph store from your Todoist projects + tasks (`mise run import-todoist`)
|
||||||
- [[self-update]] — Opt-in `hephd` self-update: poll the forge for new releases and auto-update
|
- [[self-update]] — Opt-in `hephd` self-update: poll the forge for new releases and auto-update
|
||||||
- [[heph-pwa]] — The mobile app: an installable PWA mirror of heph-tui (browse, triage, fast quick-add, voice)
|
- [[heph-pwa]] — The mobile app: an installable PWA mirror of heph-tui (browse, triage, fast quick-add, voice)
|
||||||
|
- [[host-heph-pwa]] — Serve the mobile app from the hub (indri) with OIDC, in the hub/spoke deployment
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue