docs: v0.61.0 CHANGELOG + README (F1 mem/F17 restore/F5 route) + FIXSPEC statuses + REPORT
This commit is contained in:
+25
-6
@@ -160,12 +160,16 @@ The app catalog lives in a separate Git repository. The controller:
|
||||
- User-configurable inputs (admin password, language, storage path) remain editable
|
||||
- Section header prompts the user to note down any passwords they need
|
||||
3. `checkBeforeDeploy()` JS guard fetches live state first (prevents double-deploy from another tab)
|
||||
4. **Memory validation** uses real system memory from `/proc/meminfo`:
|
||||
- `usable_memory = total_ram - reserved_memory_mb` (default 384MB reserved)
|
||||
- `system.GetMemoryMB()` returns real-time total and used memory (not declared reservations)
|
||||
- Hard block if `used_mb + new_request > usable_memory`
|
||||
- `CommittedMemory()` (declared sum) still used for soft overcommit warning only
|
||||
- Deploy page shows real memory usage bar (not declared reservations)
|
||||
4. **Memory validation** (F1, v0.61.0): the controller runs as a Docker container inside an LXC, where
|
||||
`/proc/meminfo` shows the **Proxmox host's** RAM (no lxcfs in the container) and the container's own
|
||||
cgroup is unlimited (the guest cap lives on the LXC ancestor). So the guest cap is read from the
|
||||
**Docker daemon** (`system.GuestMemTotalMB()` → `docker info` MemTotal — the daemon runs in the LXC and
|
||||
reports the guest's lxcfs-backed RAM; the cgroup limit is preferred when present, e.g. non-nested):
|
||||
- `usable_memory = guest_cap - reserved_memory_mb` (default 384MB reserved)
|
||||
- Hard block if `committed_used + new_request > usable_memory`, where `committed_used` =
|
||||
`CommittedMemory()` (sum of running apps' mem requests) — the guest-wide RSS is not observable from
|
||||
the container, so the controller's own committed accounting is the accurate, cheap "used".
|
||||
- `/api/system/info` reports the guest cap as total and committed memory as used.
|
||||
4b. **Docker-data volume reserved-buffer gate (v0.58.0, storage-split prevention layer):** the OS rootfs
|
||||
and Docker data are split onto separate volumes; infra (controller/traefik/cloudflared/filebrowser)
|
||||
shares the one Docker data-root (`/var/lib/docker`) and is protected by **prevention, not placement**.
|
||||
@@ -265,6 +269,12 @@ When app templates are updated (e.g., a new `APP_KEY` secret is added to `.felho
|
||||
| Restarting | Yellow | "Ujrainditas..." | Restart loop |
|
||||
| Not deployed | Gray | "Nincs telepitve" | Compose file exists, not deployed |
|
||||
|
||||
**Route-unpublished indicator (F5, v0.61.0).** Traefik's Docker provider only publishes a route to a
|
||||
container that is healthy (or has no healthcheck), so an `unhealthy`/`restarting` deployed app returns a
|
||||
hard **404** at its URL even though the container is running. The `routeUnpublished` template helper
|
||||
(`funcmap.go`) drives a distinct "URL nem elérhető – útvonal nincs publikálva" indicator on the dashboard
|
||||
and stacks cards for such apps, so a dead URL isn't mistaken for a merely-degraded-but-reachable one.
|
||||
|
||||
#### Controller-side Health Probes (`internal/stacks/healthprobe.go`)
|
||||
|
||||
For apps that declare a `healthcheck:` section in `.felhom.yml`, the controller probes the container directly over the Docker network (both are on `traefik-public`). This complements Docker-level healthchecks and is the **only** health mechanism for distroless/scratch images that lack shell utilities.
|
||||
@@ -404,6 +414,15 @@ backups/primary/<app>/
|
||||
env comes from `StackDataProvider.GetStackRecoveryInfo` (excludes secret-named + encrypted values, so
|
||||
the capture never touches a secret). `data_key` fields are marked in `.felhom.yml`
|
||||
(`DeployField.DataKey`).
|
||||
- **Restore replays the DB dump (F17, v0.61.0).** `RestoreFromRecoveryUnit` (and the `RestoreApp`
|
||||
fallback) stops the app → restores named-volume tars → recreates the compose definition + redeploys
|
||||
with the recovered env → **replays each `db-dumps/*.sql` into the now-running DB** via
|
||||
`backup.reimportDBDumps` → `appbackup.ImportDump` (psql / mariadb client, using the live container's own
|
||||
discovered credentials). The DB replay runs AFTER the volume restore, so the **logical SQL dump wins**
|
||||
over any volume-tar copy of the database (the dumps use DROP/CREATE — `pg_dump --clean --if-exists`,
|
||||
`mariadb-dump` default `--add-drop-table` — so replay is idempotent). Volume-restore and DB-import
|
||||
failures now **surface** (restore returns an error) instead of a swallowed WARN. Prior to v0.61.0 the
|
||||
per-app restore never replayed the `.sql`, so DB-resident data did not come back.
|
||||
|
||||
#### Tier 2 — off-drive copy (Phase 3, v0.55.x)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user