updated readme

This commit is contained in:
2026-02-21 15:45:40 +01:00
parent 538d367cc4
commit aa167b43f5
2 changed files with 88 additions and 10 deletions
+82 -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.22.0**
**Current version: v0.22.3**
---
@@ -22,6 +22,7 @@ A single, lightweight Go container that replaces Portainer + scattered systemd s
- [Central Hub](#8-central-hub-reporting)
- [Setup Wizard](#9-first-run-setup-wizard)
- [Disaster Recovery](#10-disaster-recovery)
- [Asset Sync](#11-asset-sync)
- [Repository Layout](#repository-layout)
- [Configuration](#configuration)
- [REST API](#rest-api)
@@ -58,12 +59,17 @@ A single, lightweight Go container that replaces Portainer + scattered systemd s
│ │ │ Notify │ │ REST API + Hub Reporter ││ │
│ │ │ (events) │ │ (JSON push + events) ││ │
│ │ └──────────┘ └─────────────────────────┘│ │
│ │ ┌──────────┐ │ │
│ │ │ Assets │ │ │
│ │ │ (Hub │ │ │
│ │ │ sync) │ │ │
│ │ └──────────┘ │ │
│ └────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────┘
│ events + reports │ git pull
▼ ▼
hub.felhom.eu gitea.dooplex.hu
(central dashboard) (stack definitions)
│ events + reports │ git pull │ asset sync
▼ ▼
hub.felhom.eu gitea.dooplex.hu hub.felhom.eu
(central dashboard) (stack definitions) (logos, screenshots)
```
### Key Architecture Decisions
@@ -907,6 +913,60 @@ When a system drive fails and is replaced, the recovery flow uses the setup wiza
---
### 11. Asset Sync
App assets (logos, screenshots) are managed centrally by the Hub and downloaded to each controller via a daily sync process. This decouples asset updates from controller image rebuilds — new app icons only require a Hub redeploy.
#### How It Works (`internal/assets/syncer.go`)
```
1. Fetch manifest from Hub: GET /api/v1/assets/manifest (Bearer auth)
2. Compare SHA-256 checksums with local cache (<dataDir>/assets/)
3. Download changed/new files: GET /api/v1/assets/file/{filename}
4. Remove local files not in Hub manifest (stale cleanup)
5. Save local manifest copy for next comparison
```
#### Asset Resolution (two-tier)
| Priority | Path | Source |
|----------|------|--------|
| 1 | `<dataDir>/assets/` | Downloaded from Hub (synced cache) |
| 2 | `/usr/share/felhom/assets/` | Baked into Docker image (fallback) |
The `Resolve(filename)` method checks the synced cache first, then falls back to the baked-in directory. This ensures assets are always available even before the first sync.
#### Configuration
```yaml
assets:
sync_enabled: true # Opt-in: download assets from Hub API
sync_schedule: "05:00" # Daily sync time (HH:MM, Budapest timezone)
```
Asset sync requires `hub.enabled: true` with valid `hub.url` and `hub.api_key`. The initial sync runs 10 seconds after startup (to let subsystems initialize), then daily at the configured time.
#### Sync Status
The syncer tracks status (last sync time, result, file count, total bytes) accessible via `GET /api/assets/status`. On-demand sync can be triggered via `POST /api/assets/sync`.
#### File Types
The Hub serves three asset types per app:
- `{slug}-logo.svg` — primary SVG logo
- `{slug}-logo.png` — PNG fallback
- `{slug}-screenshot-{N}.webp` — app screenshots
#### Key Design Decisions
- **Opt-in via `sync_enabled`** — backward compatible, baked-in assets still work without Hub
- **SHA-256 change detection** — only downloads files that actually changed (bandwidth efficient)
- **Atomic file writes** — downloads to `.tmp` then `os.Rename` for crash safety
- **Stale file cleanup** — removes local files not in the Hub manifest (e.g., deleted apps)
- **Non-blocking initial sync** — runs in a goroutine with 10s delay, doesn't block startup
---
## Repository Layout
```
@@ -940,6 +1000,7 @@ controller/
│ │ ├── restore_scan.go # DR: scan drives for backup data, build restore plan
│ │ ├── restore_app_linux.go # DR: per-app restore (rsync config/data + docker compose up)
│ │ └── restore_drives_linux.go # DR: auto-mount drives by UUID from Hub infra backup
│ ├── assets/syncer.go # Hub asset sync (download, SHA-256 compare, resolve)
│ ├── api/router.go # REST API endpoints (~30 routes)
│ ├── scheduler/scheduler.go # Central job scheduler (Every, Daily)
│ ├── system/
@@ -1041,6 +1102,10 @@ hub:
url: "https://hub.felhom.eu"
api_key: "bearer-token-here"
assets:
sync_enabled: true # Download app assets (logos, screenshots) from Hub API
sync_schedule: "05:00" # Daily sync time (HH:MM, Budapest timezone)
system:
reserved_memory_mb: 384 # RAM reserved for OS + controller
```
@@ -1073,6 +1138,7 @@ Auto-generated during deployment. Contains env vars, locked fields list, deploy
| metrics-prune | daily | 04:00 | Delete metrics older than 30 days |
| selfupdate-check | periodic | 6h | Check registry for new version (cache for UI) |
| selfupdate-auto | daily | 04:30 | Auto-update if enabled + backup not running |
| asset-sync | daily | 05:00 | Download changed app assets from Hub |
All daily jobs use Europe/Budapest timezone. Skip-if-running prevents concurrent execution. Panic recovery in all jobs.
@@ -1167,6 +1233,13 @@ Config endpoints accept session auth OR `Authorization: Bearer <hub_api_key>` (s
| GET | `/api/metrics/containers/{name}` | Per-container time-series |
| GET | `/api/metrics/sysinfo` | Static system info |
### Assets
| Method | Endpoint | Description |
|--------|----------|-------------|
| POST | `/api/assets/sync` | Trigger on-demand asset sync from Hub (async) |
| GET | `/api/assets/status` | Asset sync status (last sync, file count, total bytes) |
Response format: `{"ok": true/false, "data": ..., "error": "...", "message": "..."}`
---
@@ -1247,6 +1320,9 @@ See `docker-compose.yml` for the full volume configuration.
- [x] Controller self-update (v0.16.0) — Watchtower-style pull + restart, Settings page UI, API key auth, auto-update scheduling
- [x] Hub-managed config (v0.20.0) — Config apply endpoint (`POST /api/config/apply`), config hash in reports for sync comparison
- [x] Config content endpoint (v0.21.1) — `GET /api/config` returns raw YAML for Hub live diff and pull operations
- [x] First-run setup wizard (v0.22.0) — Web-based wizard replaces shell scripts, drive scan for local backups, Hub recovery, fresh install flow
- [x] Setup wizard logo fix (v0.22.2) — Use embedded SVG instead of filesystem path
- [x] Hub-managed asset sync (v0.22.3) — Download app logos/screenshots from Hub API with SHA-256 change detection, daily sync schedule
### In Progress / Planned
@@ -1262,7 +1338,7 @@ See `docker-compose.yml` for the full volume configuration.
| Node | Hardware | Domain | Status |
|------|----------|--------|--------|
| demo-felhom | Acemagic GK3PLUS N100, 16G RAM, 512G SSD + 1TB HDD | demo-felhom.eu | Controller v0.20.0 |
| demo-felhom | Acemagic GK3PLUS N100, 16G RAM, 512G SSD + 1TB HDD | demo-felhom.eu | Controller v0.22.3 |
| pi-customer-1 | Raspberry Pi 3B+, 1G RAM, 32G SD | pi-customer-1.local | Not yet tested |
## Related Repositories
+6 -4
View File
@@ -128,8 +128,10 @@ logging:
# --- Assets ---
assets:
# App logos, screenshots, and descriptions are baked into the container
# image at build time (from the felhom.eu website assets).
# Served locally at /static/assets/ — no external dependency.
# The source URL is only used during image build, not at runtime.
# App logos and screenshots are served from two sources:
# 1. Hub sync (if enabled): downloaded to <data_dir>/assets/ with SHA-256 change detection
# 2. Baked-in fallback: /usr/share/felhom/assets/ from the Docker image
# The source_url is only used during image build, not at runtime.
source_url: "https://felhom.eu"
sync_enabled: false # Set true to download assets from Hub API
sync_schedule: "05:00" # Daily sync time (HH:MM, Budapest timezone)