docs: update README for v0.27.2 architectural changes

- Memory validation: stopped apps excluded from CommittedMemory()
- Pre-start memory check (409 Conflict) on stack start
- hungarian_ui metadata field in resources
- USB badge on storage cards
- Manual Tier2 triggers now push infra backup to Hub
- showAlert() replaces native alert() for copyable error text

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-02-23 09:40:21 +01:00
parent e99067ca60
commit c33247abc1
+8 -6
View File
@@ -4,7 +4,7 @@
A single, lightweight Go container that replaces Portainer + scattered systemd scripts with a unified, Hungarian-language web dashboard for managing Docker Compose stacks, backups, storage, monitoring, and notifications on customer hardware.
**Current version: v0.26.0**
**Current version: v0.27.2**
---
@@ -138,6 +138,7 @@ The app catalog lives in a separate Git repository. The controller:
3. `checkBeforeDeploy()` JS guard fetches live state first (prevents double-deploy from another tab)
4. **Memory validation** checks `mem_request` against available RAM:
- `usable_memory = total_ram - reserved_memory_mb` (default 384MB reserved)
- `CommittedMemory()` only counts running/starting/unhealthy apps — stopped/exited apps are excluded (they don't consume RAM)
- Hard block if requests exceed usable memory
- Soft warning if limits exceed total RAM (overcommit OK)
5. Pre-generated secret values are submitted as hidden form inputs so the **same values** the user saw are saved to `app.yaml` (no silent re-generation on submit). Controller saves `app.yaml`, sets in-memory `Deployed` flag **before** `docker compose up -d` (avoids stale UI during slow image pulls), reverts on failure
@@ -149,7 +150,7 @@ The app catalog lives in a separate Git repository. The controller:
Each app can define rich metadata in `.felhom.yml`:
- `app_info`: tagline, use_cases, first_steps, prerequisites, default_creds, docs_url
- `optional_config`: groups of post-deploy configurable env vars (e.g., API keys for metadata providers)
- `resources`: mem_request, mem_limit, pi_compatible, needs_hdd
- `resources`: mem_request, mem_limit, pi_compatible, needs_hdd, hungarian_ui
The `/apps/{slug}` page renders hero section, screenshots, setup guide, and optional config form.
@@ -157,7 +158,7 @@ The `/apps/{slug}` page renders hero section, screenshots, setup guide, and opti
| Operation | What it does |
|-----------|-------------|
| Start | `docker compose up -d` |
| Start | `docker compose up -d` — pre-start memory check rejects with 409 if insufficient RAM |
| Stop | `docker compose stop` (blocked for protected stacks) |
| Restart | `docker compose restart` |
| Update | `docker compose pull` + `docker compose up -d` |
@@ -333,6 +334,7 @@ data back up config + DB + user data; apps without HDD back up config + DB dumps
- **Restic backup paths:** includes HDD mounts (if any) + config dir + per-app DB dump dir from home drive + stacks dir + controller.yaml (infra, v0.14.1)
- Safety guards: destination ≠ source, path-overlap check (HDD mounts only), writable check
- **Chained execution:** runs immediately after nightly restic — daily apps every night, weekly apps on Sundays
- **Hub reporting after manual triggers (v0.27.2):** `OnCrossDriveComplete` callback on Router pushes infra backup snapshot to Hub + writes local infra backup after both single-app and run-all manual triggers complete (previously only automatic scheduled runs reported)
- Per-app concurrency lock prevents overlapping runs
- Status (last_run, duration, size, error) persisted to settings.json
@@ -511,7 +513,7 @@ Continuously monitors registered storage paths for disconnection/reconnection (p
- Disconnected card: dashed border, red badge, timestamp, stopped apps list, "Csatlakoztatás" (reconnect) button
- After reconnect: "Alkalmazások indítása" button to restart auto-stopped stacks
**USB detection** (`system.IsUSBDevice`): Reads `/host/sys/block/<disk>` symlink — if target path contains `/usb`, it's a USB device. The `removable` sysfs flag is unreliable for USB HDDs (returns 0).
**USB detection** (`system.IsUSBDevice`): Reads `/host/sys/block/<disk>` symlink — if target path contains `/usb`, it's a USB device. The `removable` sysfs flag is unreliable for USB HDDs (returns 0). USB drives show an orange "USB" badge on their storage card alongside Aktív/Alapértelmezett badges (v0.27.2).
**Backup guards**: Nightly DB dumps, restic snapshots, and cross-drive backups all skip disconnected drives with WARN log (not treated as failures).
@@ -847,7 +849,7 @@ Bearer token authentication, 3-attempt retry with 5-second backoff. Push status
#### Infrastructure Backup to Hub (`internal/report/infra_backup.go`)
After each backup cycle, the controller pushes a full infrastructure snapshot to the Hub for disaster recovery. This snapshot includes:
After each backup cycle (including manual Tier 2 triggers via `OnCrossDriveComplete` callback), the controller pushes a full infrastructure snapshot to the Hub for disaster recovery. This snapshot includes:
- `controller.yaml` (base64-encoded, full config including secrets)
- `settings.json` (base64-encoded, backup prefs, storage paths, cross-drive configs)
- Disk layout (UUIDs, labels, mount points, fstab options, bind-mount topology)
@@ -1231,7 +1233,7 @@ All daily jobs use Europe/Budapest timezone. Skip-if-running prevents concurrent
| GET | `/api/stacks` | List all stacks |
| GET | `/api/stacks/{name}` | Stack details |
| POST | `/api/stacks/{name}/deploy` | First-time deploy |
| POST | `/api/stacks/{name}/start` | Start stack |
| POST | `/api/stacks/{name}/start` | Start stack (409 if insufficient memory) |
| POST | `/api/stacks/{name}/stop` | Stop stack |
| POST | `/api/stacks/{name}/restart` | Restart stack |
| POST | `/api/stacks/{name}/update` | Pull + recreate |