Files
tommy 4b69f74f40 lubelogger+homepage: dedicated PBS tokens
- backup job -> dedicated root@pam!lubelogger-backup token (DatastoreBackup);
  prune made non-fatal pending a group-scoped PBS prune-job (Datastore.Prune deferred).
- Homepage PBS widget -> homepage@pbs!widget (Datastore.Audit); Proxmox Beast
  (root@pam!homepage) left intact, deferred. Secrets in vault/.env only.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-02 23:40:32 -05:00
..

LubeLogger — deployment source of truth

Vehicle & small-engine maintenance tracker. Host: docker-node01 (.186). Postgres 18 backend (tables in the app schema). In-app auth ENABLED (root user).

Routing (file provider)

Published on the host at :8099; Traefik on node01 routes lubelogger.goattw.nethttp://192.168.99.186:8099 via dynamic_conf.yml (see traefik-router.dynamic_conf.yml). Edge chain: TLS (letsencrypt) → CrowdSec (global) → Authelia (authelia-auth@file, two_factor off-LAN / bypass on-LAN). LubeLogger's own auth gates the LAN/:8099 path.

Deploy (Ansible, idempotent)

Playbook deploy-lubelogger.yml (runs from ~/ansible on ansible-control):

ansible-playbook playbooks/deploy-lubelogger.yml

Inline-compose house style: copy: the compose + community.docker.docker_compose_v2. DB password is sourced from ansible-vault (vault_lubelogger_db_password) — never inline. Second converge is changed=0.

Backup (PBS) — deployed BY the playbook

The backup script + systemd units are installed and enabled by deploy-lubelogger.yml (inline, idempotent). node01, daily 03:30, one PBS snapshot (rust-usb, host/lubelogger) with three archives in a single proxmox-backup-client job, prune --keep-daily 14:

  • lubelogger-db.pxarpg_dump (app schema + data)
  • lubelogger-data.pxar/App/data volume (uploads, config, cartracker.db)
  • lubelogger-keys.pxar — ASP.NET DataProtection keyring (the ROOT USER credential + keys)

The docker-volume-backup sidecar can't target a PBS datastore natively, so the volumes ride the same pbc job as the SQL dump (one datastore, one retention). PBS token comes from ansible-vault (vault_lubelogger_pbs_token) → templated to /etc/lubelogger-backup.env (root:600, NOT in git). Restore VERIFIED: SQL round-trip into throwaway postgres:18 (row-count parity) + data/keys restore (keyring XML + a sentinel doc, byte-identical sha256). The stop-during-backup labels remain in case a sidecar is later added for a second target.

Reminders → ntfy

lubelogger-reminders-probe.{sh} + units on ansible-control (.190) — daily 07:30. Reads /api/vehicle/info (Basic auth, creds in /etc/lubelogger-reminders.env, root:600, NOT in git), posts a digest to ntfy topic garage only when something is due/overdue. Subscribe to the garage topic in your ntfy app to receive it.

Diun

App carries diun.watch_repo=true + semver include_tags so a new release tag pings the existing Diun→HA-webhook pipeline. DB (postgres:18) is watched by default (digest).

Homepage

Tile + lubelogger widget under "AI & Productivity" in observability/homepage/services.yaml (live) — widget password via HOMEPAGE_VAR_LUBELOGGER_PASSWORD (observability/.env, not a git repo). See homepage-tile.yaml.

Secrets (none in this repo)

  • DB password: ansible-vault (~/ansible), and Postgres volume (already initialized).
  • PBS token: /etc/lubelogger-backup.env (reuses vaultwarden token — a dedicated lubelogger-backup PBS token would be cleaner; needs PBS root to create).
  • Admin/basic-auth password: /etc/lubelogger-reminders.env + observability/.env.