v0.4.0: monitoring & backup — scheduler, CPU/temp metrics, healthchecks, restic backups

Phase 2 (Monitoring & Health):
- Central job scheduler replacing ad-hoc goroutines (internal/scheduler)
- CPU usage collector via /proc/stat background sampling (internal/system/cpu_linux.go)
- Temperature reading from /sys/class/thermal + /host/sys (Docker mount)
- Load average from /proc/loadavg
- Healthchecks.io-compatible HTTP pinger (internal/monitor/pinger.go)
- System health checks: disk, memory, CPU, temp, Docker, protected containers (internal/monitor/healthcheck.go)

Phase 3 (Backups):
- Database auto-discovery via docker ps + docker inspect (internal/backup/dbdump.go)
- Database dumping via docker exec (pg_dump / mariadb-dump) with atomic writes
- Restic backup integration with auto-password generation (internal/backup/restic.go)
- Backup orchestrator: DB dumps + restic snapshots + weekly prune (internal/backup/backup.go)
- Manual backup trigger via dashboard button and POST /api/backup/run

Dashboard UI:
- CPU usage bar with load average display
- Temperature with colored indicator dot
- Backup status card with last run time, DB count, repo stats
- "Mentés most" button for manual backup trigger

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-02-15 11:17:10 +01:00
parent 8a988c5998
commit d32d9fb44b
21 changed files with 2060 additions and 82 deletions
@@ -1122,6 +1122,62 @@ select.form-control option { background: var(--bg-secondary); color: var(--text-
justify-content: flex-end;
}
/* Load average text */
.system-load-avg {
font-size: .7rem;
color: var(--text-muted);
font-family: 'JetBrains Mono', monospace;
margin-top: .25rem;
}
/* Temperature dot */
.temp-dot {
display: inline-block;
width: 8px;
height: 8px;
border-radius: 50%;
margin-right: .25rem;
vertical-align: middle;
}
.temp-dot-green { background: var(--green); box-shadow: 0 0 4px rgba(35, 134, 54, 0.5); }
.temp-dot-yellow { background: var(--yellow); box-shadow: 0 0 4px rgba(210, 153, 34, 0.5); }
.temp-dot-red { background: var(--red); box-shadow: 0 0 4px rgba(218, 54, 51, 0.5); }
.system-info-item-compact {
flex: 0 1 auto;
min-width: 120px;
}
/* Backup status card */
.backup-status-card {
background: var(--bg-card);
border-radius: var(--radius);
padding: 1rem 1.25rem;
border: 1px solid var(--border-color);
margin-bottom: 2rem;
}
.backup-status-card h3 {
margin-bottom: .75rem;
}
.backup-info-row {
display: flex;
justify-content: space-between;
align-items: center;
padding: .25rem 0;
font-size: .85rem;
}
.backup-label {
color: var(--text-secondary);
}
.backup-value {
color: var(--text-primary);
font-family: 'JetBrains Mono', monospace;
font-size: .8rem;
}
.backup-status-ok { color: var(--green); }
.backup-status-fail { color: var(--red); }
.backup-status-none { color: var(--text-muted); }
/* Responsive */
@media(max-width: 768px) {
.sidebar { width: 100%; height: auto; position: relative; border-right: none; border-bottom: 1px solid var(--border-color); }