mirror of
https://github.com/Dvorinka/Dash.git
synced 2026-10-28 07:41:27 +00:00
docs: v2.0.0 changelog, configuration for auth/boards, announcement refresh
- CHANGELOG 2.0.0 entry covering all Phase 5 waves - configuration.md: transports, per-monitor alert rules, auth, boards, appearance/language, PWA - announcement.md: updated for shipped features and opt-in auth - AGENTS.md: "no auth" line was stale - ROADMAP: tick shipped M1–M3 planning checkboxes Authored By: TDvorak <[email protected]> Generated with [Devin](https://devin.ai) Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
This commit is contained in:
1 parent
0fa2ea82d8
commit
54b5497121
5 files changed
+89
-32
No files matched your search
@@ -1,7 +1,8 @@
|
|||||||
# Dash
|
# Dash
|
||||||
|
|
||||||
Self-hosted homelab dashboard. Single Go binary serving an embedded React UI.
|
Self-hosted homelab dashboard. Single Go binary serving an embedded React UI.
|
||||||
No auth, no YAML. See `ROADMAP.md` (canonical) and `docs/specs/` for design.
|
Optional auth (off by default), no YAML. See `ROADMAP.md` (canonical) and
|
||||||
|
`docs/specs/` for design.
|
||||||
|
|
||||||
## Layout
|
## Layout
|
||||||
|
|
||||||
|
|||||||
+27
-1
@@ -6,6 +6,31 @@ All notable changes to Dash. Format follows
|
|||||||
|
|
||||||
## [Unreleased]
|
## [Unreleased]
|
||||||
|
|
||||||
|
## [2.0.0] — 2026-09-22
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- Opt-in local auth: first-user setup, bcrypt passwords, SQLite sessions,
|
||||||
|
rotating 7-day HttpOnly cookie, login rate limit, sign-out/disable in
|
||||||
|
settings. Off by default; status pages, badges, metrics, push, and agent
|
||||||
|
ingest stay public
|
||||||
|
- Multiple boards: named boards with slugs, header switcher, `/b/:slug`
|
||||||
|
routes, per-board sections, board-aware export
|
||||||
|
- Full i18n: every UI string via typed `t()` keys with interpolation;
|
||||||
|
English + Czech locales, language select in settings
|
||||||
|
- Uptime bar strip + latency chart on monitor detail
|
||||||
|
- iframe embed widget and generic JSON-path widget (backend fetcher)
|
||||||
|
- Custom accent color, wallpaper URL, and custom CSS in settings
|
||||||
|
- PWA: manifest, icons, minimal service worker
|
||||||
|
- Alert transports: webhook, Slack, Discord, Telegram, Gotify, ntfy, SMTP
|
||||||
|
(stdlib `net/smtp`); transport picker + test button in settings
|
||||||
|
- Per-monitor alert rules: consecutive-failure threshold, latency warn, mute;
|
||||||
|
per-domain cert-days threshold and mute
|
||||||
|
- Per-container CPU/memory in `dash-agent` (Docker stats when socket present);
|
||||||
|
optional SMART, ZFS, and GPU collectors (exec-or-sysfs, skipped when absent)
|
||||||
|
- Subdomain discovery via Certificate Transparency + DNS, daily sweep,
|
||||||
|
subdomains section on domain detail
|
||||||
|
|
||||||
## [0.7.0] — 2026-09-21
|
## [0.7.0] — 2026-09-21
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
@@ -77,7 +102,8 @@ All notable changes to Dash. Format follows
|
|||||||
- Single Go binary serving the embedded React UI; SQLite via goose migrations;
|
- Single Go binary serving the embedded React UI; SQLite via goose migrations;
|
||||||
Docker image on distroless
|
Docker image on distroless
|
||||||
|
|
||||||
[Unreleased]: https://github.com/Dvorinka/Dash/compare/v0.7.0...HEAD
|
[Unreleased]: https://github.com/Dvorinka/Dash/compare/v2.0.0...HEAD
|
||||||
|
[2.0.0]: https://github.com/Dvorinka/Dash/compare/v0.7.0...v2.0.0
|
||||||
[0.7.0]: https://github.com/Dvorinka/Dash/compare/v0.6.0...v0.7.0
|
[0.7.0]: https://github.com/Dvorinka/Dash/compare/v0.6.0...v0.7.0
|
||||||
[0.6.0]: https://github.com/Dvorinka/Dash/compare/v0.5.0...v0.6.0
|
[0.6.0]: https://github.com/Dvorinka/Dash/compare/v0.5.0...v0.6.0
|
||||||
[0.5.0]: https://github.com/Dvorinka/Dash/compare/v0.4.0...v0.5.0
|
[0.5.0]: https://github.com/Dvorinka/Dash/compare/v0.4.0...v0.5.0
|
||||||
|
|||||||
+16
-16
@@ -149,27 +149,27 @@ becomes the summary layer over the monitoring pages.
|
|||||||
|
|
||||||
Uptime checking: the backbone everything else hangs off.
|
Uptime checking: the backbone everything else hangs off.
|
||||||
|
|
||||||
- [ ] Schema: `monitors` (name, type, url/hostname/port, method, keyword, json_query, expected_value, interval_s, timeout_s, retries, active, status, tags, notes), `heartbeats` (monitor_id, status, ping_ms, msg, cert_expiry, checked_at — 30-day retention prune)
|
- [x] Schema: `monitors` (name, type, url/hostname/port, method, keyword, json_query, expected_value, interval_s, timeout_s, retries, active, status, tags, notes), `heartbeats` (monitor_id, status, ping_ms, msg, cert_expiry, checked_at — 30-day retention prune)
|
||||||
- [ ] In-process scheduler: due-monitor sweep, bounded worker pool, heartbeat write, status transitions
|
- [x] In-process scheduler: due-monitor sweep, bounded worker pool, heartbeat write, status transitions
|
||||||
- [ ] Checkers: `http`/`https`, `tcp`, `ping` (unprivileged ICMP datagram via `x/net/icmp` — distroless has no ping binary), `dns`, `keyword`, `json-query`, `push` (caller-generated ingest URL)
|
- [x] Checkers: `http`/`https`, `tcp`, `ping` (unprivileged ICMP datagram via `x/net/icmp` — distroless has no ping binary), `dns`, `keyword`, `json-query`, `push` (caller-generated ingest URL)
|
||||||
- [ ] API: `/api/monitors` CRUD, `/:id/heartbeats?range=`, pause/resume, check-now
|
- [x] API: `/api/monitors` CRUD, `/:id/heartbeats?range=`, pause/resume, check-now
|
||||||
- [ ] Monitors page (status, uptime 24h/30d, ping, interval) + detail (response chart, heartbeat log)
|
- [x] Monitors page (status, uptime 24h/30d, ping, interval) + detail (response chart, heartbeat log)
|
||||||
- [ ] Board widget type `monitor` bound to a monitor id
|
- [x] Board widget type `monitor` bound to a monitor id
|
||||||
- [ ] ServiceDialog checkbox: create matching http monitor from a service URL
|
- [x] ServiceDialog checkbox: create matching http monitor from a service URL
|
||||||
- [ ] The fork's ~30 exotic monitor types were TCP stubs — not ported. Real types only.
|
- [x] The fork's ~30 exotic monitor types were TCP stubs — not ported. Real types only.
|
||||||
|
|
||||||
### Phase M2 — Domains → v0.5.0
|
### Phase M2 — Domains → v0.5.0
|
||||||
|
|
||||||
Domain-locker-grade domain intelligence.
|
Domain-locker-grade domain intelligence.
|
||||||
|
|
||||||
- [ ] Schema: `domains` (core columns + `extra` JSON for the long tail), `domain_history` (domain_id, change_type, field, old, new, at)
|
- [x] Schema: `domains` (core columns + `extra` JSON for the long tail), `domain_history` (domain_id, change_type, field, old, new, at)
|
||||||
- [ ] Lookup pipeline ported from fork `hub/domains/whois/lookup.go`, trimmed: RDAP over HTTPS → native WHOIS TCP:43 + parser; SSL chain via `crypto/tls`; DNS (NS/MX/TXT/A/AAAA) via `net.Resolver`; host geo via ip-api; provider detection via fork `detect/providers.go`; favicon
|
- [x] Lookup pipeline ported from fork `hub/domains/whois/lookup.go`, trimmed: RDAP over HTTPS → native WHOIS TCP:43 + parser; SSL chain via `crypto/tls`; DNS (NS/MX/TXT/A/AAAA) via `net.Resolver`; host geo via ip-api; provider detection via fork `detect/providers.go`; favicon
|
||||||
- [ ] Daily scheduler + manual refresh; field diffs recorded to `domain_history`
|
- [x] Daily scheduler + manual refresh; field diffs recorded to `domain_history`
|
||||||
- [ ] Alerts: `alert_rules` + `notifications` tables; dispatchers — generic webhook (JSON POST), SMTP via `net/smtp`, Discord/Slack presets. Triggers: domain expiry ≤ N days, SSL expiry ≤ N days, monitor down/recovered (M1), system offline (M3)
|
- [x] Alerts: `alert_rules` + `notifications` tables; dispatchers — generic webhook (JSON POST), SMTP via `net/smtp`, Discord/Slack presets. Triggers: domain expiry ≤ N days, SSL expiry ≤ N days, monitor down/recovered (M1), system offline (M3)
|
||||||
- [ ] Domains page + detail (expiry countdown, registrar, SSL, DNS, subdomains)
|
- [x] Domains page + detail (expiry countdown, registrar, SSL, DNS, subdomains)
|
||||||
- [ ] Board widget `domain` (expiry countdown)
|
- [x] Board widget `domain` (expiry countdown)
|
||||||
- [ ] Subdomain discovery: port `subdomain_discovery.go`, opt-in per domain
|
- [x] Subdomain discovery: port `subdomain_discovery.go`, opt-in per domain
|
||||||
- [ ] Not ported (v1): whoisxml API, EURid web scraping, SEO/robots parsing, valuation estimates — demand only
|
- [x] Not ported (v1): whoisxml API, EURid web scraping, SEO/robots parsing, valuation estimates — demand only
|
||||||
|
|
||||||
### Phase M3 — Systems → v0.6.0
|
### Phase M3 — Systems → v0.6.0
|
||||||
|
|
||||||
|
|||||||
+13
-8
@@ -1,11 +1,11 @@
|
|||||||
# v1.0.0 launch post — draft
|
# v2.0.0 launch post — draft
|
||||||
|
|
||||||
For r/selfhosted, HN Show, and similar. Edit freely before posting.
|
For r/selfhosted, HN Show, and similar. Edit freely before posting.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
**Title:** Dash — a self-hosted homelab dashboard with monitoring built in.
|
**Title:** Dash — a self-hosted homelab dashboard with monitoring built in.
|
||||||
Single Go binary, no YAML, no auth.
|
Single Go binary, no YAML, optional auth.
|
||||||
|
|
||||||
**Body:**
|
**Body:**
|
||||||
|
|
||||||
@@ -19,13 +19,17 @@ What it does:
|
|||||||
upload. Imports your existing Homepage (`services.yml`), Homarr, or Dashy
|
upload. Imports your existing Homepage (`services.yml`), Homarr, or Dashy
|
||||||
config in one click.
|
config in one click.
|
||||||
- **Monitors** — HTTP/TCP/ping/DNS/keyword/JSON-path checks plus push monitors
|
- **Monitors** — HTTP/TCP/ping/DNS/keyword/JSON-path checks plus push monitors
|
||||||
for cron jobs. Webhook alerts (Slack/Discord/ntfy). Uptime history.
|
for cron jobs. Uptime graphs, per-monitor alert rules, and notifications via
|
||||||
|
webhook, Slack, Discord, Telegram, Gotify, ntfy, or SMTP.
|
||||||
- **Domains** — WHOIS/RDAP, DNS, TLS certificate expiry, provider detection.
|
- **Domains** — WHOIS/RDAP, DNS, TLS certificate expiry, provider detection.
|
||||||
Inspired by Domain Locker, minus the paid APIs.
|
Inspired by Domain Locker, minus the paid APIs.
|
||||||
- **Systems** — a ~4 MB static agent pushes CPU/mem/disk/net/temps/Docker
|
- **Systems** — a ~4 MB static agent pushes CPU/mem/disk/net/temps, per-
|
||||||
container states. Inspired by Beszel, push-JSON instead of SSH.
|
container stats, and SMART/ZFS/GPU when present. Inspired by Beszel,
|
||||||
|
push-JSON instead of SSH.
|
||||||
- **Ops** — incidents, maintenance windows, public status pages, SVG badges,
|
- **Ops** — incidents, maintenance windows, public status pages, SVG badges,
|
||||||
Prometheus `/api/metrics`.
|
Prometheus `/api/metrics`.
|
||||||
|
- **Extras** — multiple boards, iframe/JSON-path widgets, CT-log subdomain
|
||||||
|
discovery, EN/CZ locales, installable PWA, custom CSS/wallpaper.
|
||||||
|
|
||||||
Deployment is one container:
|
Deployment is one container:
|
||||||
|
|
||||||
@@ -33,8 +37,9 @@ Deployment is one container:
|
|||||||
docker run -d -v ./data:/data -p 3000:3000 ghcr.io/dvorinka/dash:latest
|
docker run -d -v ./data:/data -p 3000:3000 ghcr.io/dvorinka/dash:latest
|
||||||
```
|
```
|
||||||
|
|
||||||
SQLite inside, no database to babysit, no accounts. Deliberately no auth —
|
SQLite inside, no database to babysit. Auth is opt-in: local
|
||||||
it expects a trusted LAN or your own proxy in front.
|
username/password with bcrypt + session cookies, off by default; public
|
||||||
|
status pages stay open either way.
|
||||||
|
|
||||||
Stack: Go + Gin + SQLite (single static binary serving an embedded React UI).
|
Stack: Go + Gin + SQLite (single static binary serving an embedded React UI).
|
||||||
MIT licensed.
|
MIT licensed.
|
||||||
@@ -53,5 +58,5 @@ Show HN: Dash – self-hosted homelab dashboard with monitoring, one Go binary
|
|||||||
|
|
||||||
Dash combines a service board, uptime monitors, domain/SSL watching, system
|
Dash combines a service board, uptime monitors, domain/SSL watching, system
|
||||||
metrics via a tiny push agent, and public status pages. Single container or
|
metrics via a tiny push agent, and public status pages. Single container or
|
||||||
single binary, SQLite storage, no YAML, no auth (LAN-trust model). MIT.
|
single binary, SQLite storage, no YAML. Optional local auth. MIT.
|
||||||
https://github.com/Dvorinka/Dash
|
https://github.com/Dvorinka/Dash
|
||||||
+31
-6
@@ -21,12 +21,16 @@ snapshot; `/api/import/csv` bulk-loads monitors and domains from CSV.
|
|||||||
|
|
||||||
## Notifications
|
## Notifications
|
||||||
|
|
||||||
**Settings → Notifications** holds one generic webhook URL
|
**Settings → Notifications** configures any number of transports — generic
|
||||||
(`notify_webhook`). On monitor up/down transitions and domain events, Dash
|
webhook, Slack, Discord, Telegram, Gotify, ntfy, and SMTP — each stored as a
|
||||||
POSTs a JSON payload with `event`, `name`, `text`, `content`, `message`, and
|
`notify_<name>` settings object. Monitor up/down transitions and domain
|
||||||
`at` fields — shaped so Slack, Discord, and ntfy all render it sensibly.
|
events fan out to every configured transport; the payload carries `event`,
|
||||||
**Test** sends a `test` event. Delivery is async and non-fatal; failures are
|
`name`, `text`, `content`, `message`, and `at` fields. **Test** sends a `test`
|
||||||
logged.
|
event. Delivery is async and non-fatal; failures are logged.
|
||||||
|
|
||||||
|
Per-monitor alert rules (consecutive failures before down, latency-warn ms,
|
||||||
|
mute) live on each monitor; domains get a cert-days threshold and mute.
|
||||||
|
Maintenance windows still take precedence.
|
||||||
|
|
||||||
## Monitors
|
## Monitors
|
||||||
|
|
||||||
@@ -47,6 +51,27 @@ Bearer-token push ingest at `POST /api/systems/ingest`. A system is marked
|
|||||||
offline when no sample arrives within a few intervals. Stats are pruned during
|
offline when no sample arrives within a few intervals. Stats are pruned during
|
||||||
the hourly sweep.
|
the hourly sweep.
|
||||||
|
|
||||||
|
## Auth
|
||||||
|
|
||||||
|
Off by default — existing installs see no gate. **Settings → Authentication →
|
||||||
|
Enable** flips to a first-user setup screen (username/email + password,
|
||||||
|
bcrypt). Sessions are SQLite-backed 7-day HttpOnly cookies with rotation;
|
||||||
|
login is rate-limited per IP. Disable only works from an authenticated
|
||||||
|
session. Public status pages, badges, `/api/metrics`, `/api/push/*`, and
|
||||||
|
agent ingest stay open under auth.
|
||||||
|
|
||||||
|
## Boards
|
||||||
|
|
||||||
|
The header switcher manages multiple boards — each gets a slug and a
|
||||||
|
`/b/:slug` route with its own sections/items. Monitors, domains, systems, and
|
||||||
|
status pages stay global. Exports carry all boards.
|
||||||
|
|
||||||
|
## Appearance & language
|
||||||
|
|
||||||
|
Theme (dark/light), accent color, wallpaper URL, and custom CSS in Settings;
|
||||||
|
the language picker switches the UI between English and Czech. A PWA manifest
|
||||||
|
and service worker make the app installable.
|
||||||
|
|
||||||
## Operations
|
## Operations
|
||||||
|
|
||||||
- **Incidents** — open/ack/resolve/close, with per-incident update timeline.
|
- **Incidents** — open/ack/resolve/close, with per-incident update timeline.
|
||||||
|
|||||||
Reference in new issue
Block a user