What you get
One Go binary serves the web app, the API, and an MCP endpoint
(off until an admin turns it on — see MCP setup).
The build embeds the web UI, and the default storage engine is
SQLite — the executable and one database file are the whole install.
If you prefer a database server, point it at PostgreSQL instead
(EAG_DB_DRIVER=postgres). Either way the server applies its
own schema on every boot (idempotently, serialised per driver), so there
is no separate migration step on any path. The binary also carries its
own reference documentation at /docs, so every install
ships the docs that match its version. The latest release's copy is
hosted here as the app reference.
Every release publishes, from the Eagraí Clainne repository:
- CLI builds for Linux and macOS (amd64, arm64) on the releases page, with checksums
- a signed Android APK on the same releases page:
eagraiclainne_vX.Y.Z.apk - a multi-arch server container image:
forgejo.lihnet.mallon.ie/eagraiclainne/app - a TrueNAS SCALE Custom App file, pinned to the release:
eagraiclainne-truenas_vX.Y.Z.yaml - a Timoni module:
oci://forgejo.lihnet.mallon.ie/eagraiclainne/timoni - rendered Kubernetes manifests for Flux:
oci://forgejo.lihnet.mallon.ie/eagraiclainne/manifests
forgejo.lihnet.mallon.ie and a token with package:read
(plus repository:read for release downloads and clones). The
current release is v1.0.0. Every example on these pages pins
it.Pick your path
Five ways to run the server, two clients to talk to it. Each server guide is complete and ends with a working install. Storage defaults to SQLite, so none of them needs a database server any more.
| Guide | Choose it when |
|---|---|
| Bare metal | You run services with systemd and want no containers anywhere:
build from source, unit file, data in one file under
/var/lib. |
| Container | You have Docker on the box: one compose service, one named volume for the database file. |
| TrueNAS SCALE | Your home server is a TrueNAS box: paste the released Custom App file into the Apps screen, data on a dataset you own. |
| Flux GitOps | You run Kubernetes and Flux: point an OCIRepository at the released manifests and let the cluster reconcile a PVC-backed install. |
| Timoni | You run Kubernetes without an in-cluster operator: apply the released CUE module client-side. This is also the path that exposes the optional PostgreSQL backend. |
| CLI | The server is already running somewhere and you want to work the board from the terminal: users, events, items, rewards, API keys, backups, and a full-screen TUI. |
| Android app | The server is running and you want the board on the family's phones: install the signed APK from the releases page. |
The Android app
Each release attaches a signed APK
(eagraiclainne_v1.0.0.apk) to the
releases page.
It runs on Android 8.0 or newer and carries the same boards as the web
app: Today, Calendar, Jobs, Lists, Meals, Rewards. Like the web app it
works offline — reads come from a local cache, writes queue and replay
when the connection returns.
Install it by sideloading the APK, or point
Obtainium at the
repository to pick up new releases as they land. On first start the app
asks for the server address — the same address in the phone's browser,
for example http://your-server:8080. Push notifications ride
UnifiedPush (ntfy or any other
distributor), so no Google services are involved.
First sign-in
Open http://your-server:8080. An empty install greets you
with a welcome screen and a form to create the first admin account — that is
how Síle set up her household: name, email, password, and she was on the
board. From there, Family → Add member brings in everyone else. Each person
picks their mark and theme the first time they sign in.
Where your data lives
In one SQLite file, on your hardware — EAG_DB_PATH names
it, and each install path picks a sensible home (a
/var/lib directory, a Docker volume, a PVC). If you prefer a
database server, set EAG_DB_DRIVER=postgres and the usual
EAG_DB_* connection settings. On either driver the app makes
no external requests, sets no analytics, and phones nothing home. The
server keeps no state outside the database, not even its JWT signing
secret, which lives in the database too.
Backup and restore
The server exports its whole state as one versioned archive
(.json.gz), on demand, in two modes. Backup carries
everything, including credentials and secrets, and is the archive a
restore accepts. Portable carries the family's content with every
secret scrubbed — safe to hand over. Admins find both as download buttons under
Admin → System, or from the CLI:
eagraiclainne system export --mode backup -o eagraiclainne-backup.json.gz
# fresh install: restore before the first admin exists
eagraiclainne system import eagraiclainne-backup.json.gz
# populated install: requires admin auth and the explicit wipe
eagraiclainne system import eagraiclainne-backup.json.gz --wipe
The archive works across install paths and storage drivers — export from a PostgreSQL install, import into a SQLite one, or the reverse. A plain copy of the SQLite file (or a dump of the PostgreSQL database) works too. The archive is the portable, driver-neutral form.
Separate from the whole-family archive, each member can take their
own data with them: a scrubbed .json.gz of the items,
events, rewards, and history that belong to them — never credentials,
keys, or anyone else's records. Members find it under Settings (web and
Android), admins can export any member under Admin, and the CLI does
both:
eagraiclainne user export # your own data
eagraiclainne user export --user <uid> # any member's (admin)
Telemetry (OTLP)
The server is instrumented with OpenTelemetry across all three
signals — traces, metrics, and logs. By default they go to stdout
(journald on bare metal,
docker compose logs in a container)
and nothing leaves the box. This is operational telemetry about your own
server, for you — not analytics. It goes only where you point it.
When you want dashboards instead of log lines — request rates,
latencies, traces through a slow call, one place to search logs —
point the exporter at an OpenTelemetry collector. The app repository
ships a single-pod
observability stack
(grafana/otel-lgtm: collector, Tempo, Mimir, Loki, Grafana)
with Eagraí Clainne dashboards included.
Three settings drive it, on every install path:
| Variable | Default | Purpose |
|---|---|---|
EAG_OTLP_ENDPOINT | (empty) | Collector
host:port. Empty keeps the stdout exporters |
EAG_OTLP_PROTOCOL | grpc | Transport:
grpc or http |
EAG_OTLP_INSECURE | false | Skip TLS — for a collector inside the same cluster or host |
# example: export to a collector on the LAN
EAG_OTLP_ENDPOINT=otel.lihnet.mallon.ie:4317
EAG_OTLP_INSECURE=true
Telemetry is off by default on every path (since v0.6.0).
To opt in: bare metal and
container set the variables
directly. Timoni exposes them as
config.otlp values. Flux
adds them with a patches block on the Kustomization.