mirror of
https://github.com/Studio-Saelix/sencho.git
synced 2026-07-26 11:49:16 +00:00
32a7d53b2b
* feat: add RBAC viewer accounts, atomic deployments, and fleet-wide backups (Pro) Introduces three Pro-tier features: - RBAC: Multi-user system with admin/viewer roles, user management UI, automatic migration from single-admin credentials, viewer restrictions across the entire UI (read-only editor, hidden action buttons) - Atomic Deployments: Pre-deploy file backup to .sencho-backup/, automatic rollback on health probe failure, manual rollback button, health probes added to stack updates, webhook-triggered deploys use atomic rollback - Fleet-Wide Backups: Point-in-time snapshots of compose files across all nodes (local + remote), stored centrally in SQLite, per-stack restore with optional redeploy, graceful handling of offline nodes * fix(settings): use correct ProGate prop name in UsersSection * fix(settings): remove unused isPro prop from UsersSection * fix(auth): fetch user info after login and setup so isAdmin is set correctly * feat(pricing): revise pricing strategy and enforce variant-based seat limits Raise Personal Pro from $49/yr to $69/yr with 3 viewer seats (up from 1). Add $15/mo billing option for Team Pro. Mark lifetime pricing as a 90-day early-adopter offer. Store Lemon Squeezy variant_name on activation/validation and enforce seat limits server-side per variant. * feat(licensing): add Lemon Squeezy checkout, webhook, and billing portal integration Server-side checkout URL generation (POST /api/checkout) with admin email pre-fill and instance_id custom data. HMAC-SHA256 verified webhook endpoint (POST /api/webhooks/lemonsqueezy) handling order, subscription, and payment lifecycle events for automatic license activation. Customer billing portal link stored from webhook events and exposed via GET /api/billing/portal. In-app checkout buttons in Settings with manual license key fallback. * fix(licensing): exempt Lemon Squeezy webhook from auth middleware The catch-all auth middleware on /api/* was blocking the public webhook endpoint. Added /webhooks/lemonsqueezy to the exemption list alongside /auth/* and /webhooks/:id/trigger. * feat(pricing): update pricing to final live rates Personal Pro: $7.99/month, $69.99/year, $249 lifetime. Team Pro: $49.99/month, $499.99/year, $1,499 lifetime. Added personal_monthly checkout variant across backend, frontend, and website. * refactor(licensing): remove server-side checkout/webhook for self-hosted model Sencho is self-hosted — each user runs their own instance, so there is no central server to receive webhooks or hold the store API key. Replaced in-app checkout buttons with a "View Pricing" redirect to sencho.io and kept manual license key activation as the primary flow. - Delete LemonSqueezyService (checkout, webhook, HMAC verification) - Remove POST /api/checkout, GET /api/billing/portal, POST /api/webhooks/lemonsqueezy - Remove raw body parser and auth exemption for webhook route - Remove all LEMONSQUEEZY_* env vars from .env.example - Replace checkout buttons in SettingsModal with single "View Pricing" button - Simplify LicenseContext checkout to open sencho.io pricing page - Update licensing docs to reflect website-based purchase flow * chore: normalize em-dashes to hyphens across codebase (linter) * chore: remove accidentally tracked directories from index
119 lines
4.3 KiB
Plaintext
119 lines
4.3 KiB
Plaintext
---
|
|
title: Fleet View
|
|
description: Monitor all your nodes from a single dashboard with real-time health metrics, search, filtering, and container drill-down.
|
|
---
|
|
|
|
The **Fleet** tab gives you a bird's-eye view of every node in your Sencho deployment - local and remote - on one screen. It is available to all tiers, with advanced features unlocked by Sencho Pro.
|
|
|
|
<Frame>
|
|
<img src="/images/fleet-view/fleet-overview.png" alt="Fleet View showing health summary cards, toolbar, and node grid" />
|
|
</Frame>
|
|
|
|
## Community features
|
|
|
|
Every Sencho installation gets the full fleet monitoring grid at no cost.
|
|
|
|
### Node grid
|
|
|
|
Each node appears as a card showing:
|
|
|
|
| Data | Description |
|
|
|------|-------------|
|
|
| **Status badge** | Online (green) or Offline (grayed out) |
|
|
| **Type badge** | `local` or `remote` |
|
|
| **Running containers** | Count of containers in `running` state |
|
|
| **Stopped containers** | Count of containers in `exited` state |
|
|
| **Stacks** | Total number of Compose stacks on the node |
|
|
| **CPU usage** | Current percentage with colour-coded bar (green → amber → red) |
|
|
| **RAM usage** | Used / total with percentage bar |
|
|
| **Disk usage** | Used / total with percentage bar |
|
|
|
|
Offline nodes are visually dimmed and show a "Node unreachable" placeholder instead of stats.
|
|
|
|
### Manual refresh
|
|
|
|
Click the **Refresh** button in the top-right to re-fetch data from all nodes. The button shows a spinner while loading.
|
|
|
|
---
|
|
|
|
## Pro features
|
|
|
|
<Note>
|
|
The features below require a Sencho Pro license. Community users see an upgrade prompt in place of these controls.
|
|
</Note>
|
|
|
|
### Fleet health summary cards
|
|
|
|
Four cards appear above the node grid, aggregating data across all online nodes:
|
|
|
|
| Card | What it shows |
|
|
|------|---------------|
|
|
| **Containers** | Total running containers, with fleet-wide total in subtitle |
|
|
| **Fleet CPU** | Average CPU across all online nodes, plus which node has the highest load |
|
|
| **Fleet Memory** | Total RAM used / total available across the fleet |
|
|
| **Alerts** | Count of nodes with critical resource usage (CPU or disk above 90%). Card turns red when any exist |
|
|
|
|
### Auto-refresh
|
|
|
|
Fleet data automatically refreshes every 30 seconds. A subtle indicator at the bottom of the page confirms this is active.
|
|
|
|
### Search
|
|
|
|
The search bar filters the node grid in real time. It matches against:
|
|
- Node names (e.g. typing `dev` shows only nodes with "dev" in the name)
|
|
- Stack names (e.g. typing `plex` shows only nodes that have a "plex" stack)
|
|
|
|
### Sorting
|
|
|
|
Use the sort dropdown to order nodes by:
|
|
- **Name** (alphabetical)
|
|
- **CPU Usage** (highest first)
|
|
- **Memory Usage** (highest first)
|
|
- **Containers** (most first)
|
|
- **Status** (online first)
|
|
|
|
Click the arrow button next to the dropdown to toggle ascending/descending.
|
|
|
|
Sort preferences are saved to your browser and persist across sessions.
|
|
|
|
### Filtering
|
|
|
|
Filter pills let you narrow the grid:
|
|
|
|
| Filter | Options |
|
|
|--------|---------|
|
|
| **Status** | All · Online · Offline |
|
|
| **Type** | All Types · Local · Remote |
|
|
| **Critical Only** | Show only nodes with CPU or disk above 90% |
|
|
|
|
A "Clear filters" button appears when filters hide all nodes.
|
|
|
|
### Stack drill-down
|
|
|
|
Click **Stack details** on any online node card to expand the stack list. Each stack shows a count of its containers.
|
|
|
|
Click a stack name to expand it further and see individual containers with:
|
|
- Container name
|
|
- State badge (running, exited, restarting)
|
|
- Uptime (e.g. "Up 43 hours")
|
|
|
|
Hover over any container row to reveal an **Open in editor** button that navigates you directly to that node's stack editor.
|
|
|
|
<Frame>
|
|
<img src="/images/fleet-view/fleet-drill-down.png" alt="Fleet View with stack expanded showing container details" />
|
|
</Frame>
|
|
|
|
### Critical node detection
|
|
|
|
Nodes with CPU or disk usage above 90% automatically receive a red **Critical** badge. Combined with the **Critical Only** filter, this lets you quickly triage overloaded servers.
|
|
|
|
---
|
|
|
|
## How fleet data is fetched
|
|
|
|
Fleet View queries all registered nodes in parallel. Each node responds independently - one slow or offline node does not block the others. Local node data comes from the Docker socket and system stats directly. Remote node data is fetched over the Distributed API proxy using each node's Bearer token.
|
|
|
|
<Note>
|
|
Fleet View always runs on your primary (local) Sencho instance. It is never proxied through a remote node.
|
|
</Note>
|