mirror of
https://github.com/Studio-Saelix/sencho.git
synced 2026-08-13 12:17:34 +00:00
feat: RBAC, atomic deployments, fleet backups, and licensing (Pro) (#185)
* 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
This commit is contained in:
+2
-1
@@ -40,7 +40,8 @@
|
||||
"features/webhooks",
|
||||
"features/rbac",
|
||||
"features/atomic-deployments",
|
||||
"features/fleet-backups"
|
||||
"features/fleet-backups",
|
||||
"features/licensing"
|
||||
]
|
||||
},
|
||||
{
|
||||
|
||||
@@ -3,7 +3,7 @@ title: App Store
|
||||
description: Browse and deploy pre-configured application templates in one click.
|
||||
---
|
||||
|
||||
The **App Store** tab lets you browse a curated catalogue of Docker Compose templates and deploy any of them as a new stack with environment-specific configuration — no YAML required.
|
||||
The **App Store** tab lets you browse a curated catalogue of Docker Compose templates and deploy any of them as a new stack with environment-specific configuration - no YAML required.
|
||||
|
||||
<Frame>
|
||||
<img src="/images/app-store/app-store-overview.png" alt="App Store showing a grid of application templates with category filters" />
|
||||
@@ -30,7 +30,7 @@ Click any template card to open the **deployment sheet** on the right side of th
|
||||
|
||||
### Stack name
|
||||
|
||||
Pre-filled with the template name in lowercase. You can change it — the same [naming rules](/features/stack-management#creating-a-stack) apply (lowercase, hyphens, no spaces).
|
||||
Pre-filled with the template name in lowercase. You can change it - the same [naming rules](/features/stack-management#creating-a-stack) apply (lowercase, hyphens, no spaces).
|
||||
|
||||
### Environment variables
|
||||
|
||||
@@ -48,7 +48,7 @@ For each container mount point, enter the **host path** where that data should b
|
||||
|
||||
### Ports
|
||||
|
||||
For each exposed port, edit the **host port** (left side). The container port (right side) is fixed by the template and cannot be changed here — edit the compose file after deployment if needed.
|
||||
For each exposed port, edit the **host port** (left side). The container port (right side) is fixed by the template and cannot be changed here - edit the compose file after deployment if needed.
|
||||
|
||||
### What happens on Deploy
|
||||
|
||||
|
||||
@@ -11,12 +11,12 @@ Sencho Pro wraps every deployment in a safety net. Before applying changes, it b
|
||||
|
||||
## How it works
|
||||
|
||||
1. **Backup** — Before a deploy or update, Sencho copies `compose.yaml` and `.env` files to a `.sencho-backup/` directory inside the stack folder
|
||||
2. **Deploy** — Sencho runs the requested compose operation (up, pull + recreate, etc.)
|
||||
3. **Health probe** — After deployment, Sencho checks whether any containers exited with a non-zero exit code
|
||||
4. **Auto-rollback** — If a crash is detected, Sencho restores the backed-up files and re-deploys automatically
|
||||
1. **Backup** - Before a deploy or update, Sencho copies `compose.yaml` and `.env` files to a `.sencho-backup/` directory inside the stack folder
|
||||
2. **Deploy** - Sencho runs the requested compose operation (up, pull + recreate, etc.)
|
||||
3. **Health probe** - After deployment, Sencho checks whether any containers exited with a non-zero exit code
|
||||
4. **Auto-rollback** - If a crash is detected, Sencho restores the backed-up files and re-deploys automatically
|
||||
|
||||
This entire sequence happens transparently. You see a single deploy action — Sencho handles the safety logic behind the scenes.
|
||||
This entire sequence happens transparently. You see a single deploy action - Sencho handles the safety logic behind the scenes.
|
||||
|
||||
## Manual rollback
|
||||
|
||||
@@ -30,4 +30,4 @@ Deployments triggered via webhooks also use atomic rollback. Whether you deploy
|
||||
|
||||
## Community Edition behavior
|
||||
|
||||
Community users continue to use the standard deploy flow — no backup is created and no rollback is available. Upgrading to Pro enables atomic deployments immediately with no configuration required.
|
||||
Community users continue to use the standard deploy flow - no backup is created and no rollback is available. Upgrading to Pro enables atomic deployments immediately with no configuration required.
|
||||
|
||||
@@ -15,7 +15,7 @@ The top row summarises container state at a glance:
|
||||
|
||||
| Card | What it shows |
|
||||
|------|---------------|
|
||||
| **Active Containers** | Running containers — broken down as `N managed · N external` |
|
||||
| **Active Containers** | Running containers - broken down as `N managed · N external` |
|
||||
| **Exited Containers** | Stopped or crashed containers |
|
||||
| **Docker Network** | Current inbound/outbound network throughput across all containers |
|
||||
|
||||
@@ -37,8 +37,8 @@ When any value exceeds configured thresholds (set in **Settings → System Limit
|
||||
|
||||
Two area charts display time-series data sampled at one-minute intervals, retained for up to 24 hours (configurable in **Settings → Developer**):
|
||||
|
||||
- **Normalized CPU Usage** — total CPU percentage across all managed containers, normalised over all host cores
|
||||
- **Normalized RAM Usage** — total memory allocated by managed containers, in GB
|
||||
- **Normalized CPU Usage** - total CPU percentage across all managed containers, normalised over all host cores
|
||||
- **Normalized RAM Usage** - total memory allocated by managed containers, in GB
|
||||
|
||||
The x-axis shows time labels. Hover over a data point to see the exact value at that moment.
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ title: Editor
|
||||
description: Edit compose files and environment variables, and manage containers directly from the dashboard.
|
||||
---
|
||||
|
||||
Selecting a stack opens the editor view — a split-pane layout with container management on the left and a full Monaco code editor on the right.
|
||||
Selecting a stack opens the editor view - a split-pane layout with container management on the left and a full Monaco code editor on the right.
|
||||
|
||||
<Frame>
|
||||
<img src="/images/editor/editor-overview.png" alt="Editor view showing container panel and Monaco editor" />
|
||||
@@ -37,9 +37,9 @@ The `.env` editor has the same save/discard controls as the compose editor. Chan
|
||||
|
||||
The left panel lists all containers that belong to the selected stack. Each container shows:
|
||||
|
||||
- **Status badge** — `running`, `exited`, `starting`, or `unhealthy`
|
||||
- **Live stats** — CPU %, RAM usage, and network I/O updated every 1–2 seconds
|
||||
- **Port mappings** — host:container port pairs (if any)
|
||||
- **Status badge** - `running`, `exited`, `starting`, or `unhealthy`
|
||||
- **Live stats** - CPU %, RAM usage, and network I/O updated every 1–2 seconds
|
||||
- **Port mappings** - host:container port pairs (if any)
|
||||
|
||||
### Container actions
|
||||
|
||||
@@ -57,7 +57,7 @@ The log viewer streams output from a single container in real-time using Server-
|
||||
|
||||
### Container terminal (exec)
|
||||
|
||||
The terminal modal gives you an interactive bash shell inside the running container — equivalent to `docker exec -it <id> bash`. It uses a full xterm.js emulator with color support and tab completion.
|
||||
The terminal modal gives you an interactive bash shell inside the running container - equivalent to `docker exec -it <id> bash`. It uses a full xterm.js emulator with color support and tab completion.
|
||||
|
||||
<Warning>
|
||||
The container terminal requires the container to have `bash` (or `sh`) installed. Minimal images (e.g. Alpine-based) may need `sh` instead.
|
||||
|
||||
@@ -7,28 +7,28 @@ description: Snapshot compose files across all nodes for disaster recovery and a
|
||||
Fleet-Wide Backups require a Sencho Pro license. The feature is available to Pro admins in the Fleet View.
|
||||
</Note>
|
||||
|
||||
Create point-in-time snapshots of every `compose.yaml` and `.env` file across your entire fleet — local and remote nodes alike. Snapshots are stored centrally in Sencho's database and can be browsed, previewed, and restored at any time.
|
||||
Create point-in-time snapshots of every `compose.yaml` and `.env` file across your entire fleet - local and remote nodes alike. Snapshots are stored centrally in Sencho's database and can be browsed, previewed, and restored at any time.
|
||||
|
||||
## Creating a snapshot
|
||||
|
||||
1. Navigate to **Fleet View** and select the **Snapshots** tab
|
||||
2. Click **Create Snapshot**
|
||||
3. Optionally enter a description (e.g. "Before v2 migration")
|
||||
4. Click **Create** — Sencho captures files from every reachable node
|
||||
4. Click **Create** - Sencho captures files from every reachable node
|
||||
|
||||
During creation, Sencho connects to each node in parallel:
|
||||
- **Local nodes** — reads files directly from the compose directory
|
||||
- **Remote nodes** — fetches files via the Distributed API proxy using the node's API token
|
||||
- **Local nodes** - reads files directly from the compose directory
|
||||
- **Remote nodes** - fetches files via the Distributed API proxy using the node's API token
|
||||
|
||||
If a remote node is offline or unreachable, it is **skipped gracefully**. The snapshot is still created with data from all reachable nodes, and skipped nodes are recorded with the reason for the failure.
|
||||
|
||||
## Browsing snapshots
|
||||
|
||||
The snapshot list shows:
|
||||
- **Date** — when the snapshot was taken
|
||||
- **Description** — your optional label
|
||||
- **Scope** — how many nodes and stacks were captured
|
||||
- **Warnings** — an indicator if any nodes were skipped
|
||||
- **Date** - when the snapshot was taken
|
||||
- **Description** - your optional label
|
||||
- **Scope** - how many nodes and stacks were captured
|
||||
- **Warnings** - an indicator if any nodes were skipped
|
||||
|
||||
Click **View** to open the detail view, which presents a collapsible tree:
|
||||
|
||||
@@ -58,8 +58,8 @@ Admins can restore individual stacks from any snapshot:
|
||||
5. Confirm the action
|
||||
|
||||
Sencho writes the snapshot's files back to the target node:
|
||||
- **Local nodes** — files are written directly, and the current files are backed up first (creating a rollback point via the atomic deployment system)
|
||||
- **Remote nodes** — files are pushed via the Distributed API proxy
|
||||
- **Local nodes** - files are written directly, and the current files are backed up first (creating a rollback point via the atomic deployment system)
|
||||
- **Remote nodes** - files are pushed via the Distributed API proxy
|
||||
|
||||
<Warning>
|
||||
Restoring overwrites the current compose and environment files on the target node. If atomic deployments are enabled, the current files are backed up before restoration.
|
||||
|
||||
@@ -3,7 +3,7 @@ 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.
|
||||
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" />
|
||||
@@ -111,7 +111,7 @@ Nodes with CPU or disk usage above 90% automatically receive a red **Critical**
|
||||
|
||||
## 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.
|
||||
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.
|
||||
|
||||
@@ -3,7 +3,7 @@ title: Global Observability
|
||||
description: A unified, searchable log stream from every container across all your stacks.
|
||||
---
|
||||
|
||||
The **Logs** tab aggregates output from all running containers into a single scrollable view. Instead of tailing logs one container at a time, you see everything in one place — with filtering to focus on what matters.
|
||||
The **Logs** tab aggregates output from all running containers into a single scrollable view. Instead of tailing logs one container at a time, you see everything in one place - with filtering to focus on what matters.
|
||||
|
||||
<Frame>
|
||||
<img src="/images/global-observability/global-observability-overview.png" alt="Global Observability view showing real-time log lines from multiple containers" />
|
||||
@@ -13,11 +13,11 @@ The **Logs** tab aggregates output from all running containers into a single scr
|
||||
|
||||
Each line shows:
|
||||
|
||||
- **Timestamp** — when the log line was emitted
|
||||
- **Stack name** — the Compose stack the container belongs to (colour-coded)
|
||||
- **Container name** — the specific container
|
||||
- **Level** — `INFO`, `WARN`, or `ERROR` (where detectable)
|
||||
- **Message** — the raw log output
|
||||
- **Timestamp** - when the log line was emitted
|
||||
- **Stack name** - the Compose stack the container belongs to (colour-coded)
|
||||
- **Container name** - the specific container
|
||||
- **Level** - `INFO`, `WARN`, or `ERROR` (where detectable)
|
||||
- **Message** - the raw log output
|
||||
|
||||
## Streaming modes
|
||||
|
||||
@@ -36,11 +36,11 @@ Use the controls above the log panel to narrow what you see:
|
||||
|
||||
| Control | What it does |
|
||||
|---------|-------------|
|
||||
| **Stack filter** | Multi-select dropdown — show only logs from chosen stacks |
|
||||
| **Stream** | `ALL` / `STDOUT` / `STDERR` — filter by output stream |
|
||||
| **Stack filter** | Multi-select dropdown - show only logs from chosen stacks |
|
||||
| **Stream** | `ALL` / `STDOUT` / `STDERR` - filter by output stream |
|
||||
| **Search** | Full-text filter on the message field (case-insensitive) |
|
||||
|
||||
Filters combine — you can show only `STDERR` from a specific stack while searching for a keyword.
|
||||
Filters combine - you can show only `STDERR` from a specific stack while searching for a keyword.
|
||||
|
||||
## Controls
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
---
|
||||
title: Host Console
|
||||
description: An interactive terminal on your host OS, directly in the browser — no SSH required.
|
||||
description: An interactive terminal on your host OS, directly in the browser - no SSH required.
|
||||
---
|
||||
|
||||
The **Console** tab opens a full interactive terminal session on the machine running Sencho. It behaves exactly like an SSH session, but without needing an SSH server, client, or key management.
|
||||
@@ -32,7 +32,7 @@ Click **Close Console** to end the session and terminate the shell process on th
|
||||
|
||||
The shell depends on the host OS:
|
||||
- **Linux/macOS hosts:** `bash` or `sh`
|
||||
- **Windows hosts (Docker Desktop):** PowerShell (as shown in the screenshot — the console opens inside the Sencho container's Windows environment)
|
||||
- **Windows hosts (Docker Desktop):** PowerShell (as shown in the screenshot - the console opens inside the Sencho container's Windows environment)
|
||||
|
||||
## Security model
|
||||
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
---
|
||||
title: Licensing & Billing
|
||||
description: How Sencho Pro licensing works - trials, activation, and subscription management.
|
||||
---
|
||||
|
||||
Sencho uses an open-core model. The **Community** tier is free forever with unlimited nodes. **Pro** unlocks advanced features like fleet management, RBAC, webhooks, atomic deployments, and fleet-wide backups.
|
||||
|
||||
## Plans
|
||||
|
||||
| Tier | Price | Accounts |
|
||||
|------|-------|----------|
|
||||
| **Community** | Free | 1 admin |
|
||||
| **Personal Pro** | $7.99/month, $69.99/year, or $249 lifetime | 1 admin + 3 viewers |
|
||||
| **Team Pro** | $49.99/month, $499.99/year, or $1,499 lifetime | Unlimited |
|
||||
|
||||
Lifetime pricing is an early-adopter offer available for a limited time only.
|
||||
|
||||
## Free trial
|
||||
|
||||
Every new Sencho installation starts with a **14-day Pro trial** - no license key or credit card required. All Pro features are unlocked during the trial so you can evaluate them with your real infrastructure.
|
||||
|
||||
When the trial expires, Sencho automatically reverts to the Community tier. No data is lost.
|
||||
|
||||
## Purchasing a license
|
||||
|
||||
1. Visit [sencho.io](https://sencho.io/#pricing) and choose a plan.
|
||||
2. Complete the checkout on Lemon Squeezy.
|
||||
3. You'll receive a license key by email.
|
||||
|
||||
## Activating your license
|
||||
|
||||
1. Go to **Settings > License** in your Sencho dashboard.
|
||||
2. Paste your key into the **License Key** field.
|
||||
3. Click **Activate**.
|
||||
|
||||
Sencho validates the key against Lemon Squeezy and activates Pro features immediately.
|
||||
|
||||
## License validation
|
||||
|
||||
Active licenses are re-validated every **72 hours** against the Lemon Squeezy API. If your instance goes offline, there is a **30-day grace period** before it degrades to the Community tier.
|
||||
|
||||
## Managing your subscription
|
||||
|
||||
To manage your subscription (update payment method, view invoices, cancel, or switch plans), visit the [Lemon Squeezy customer portal](https://app.lemonsqueezy.com/my-orders) or use the link in your purchase confirmation email.
|
||||
|
||||
## Deactivating a license
|
||||
|
||||
To transfer your license to a different instance:
|
||||
|
||||
1. Go to **Settings > License**.
|
||||
2. Click **Deactivate License**.
|
||||
3. On your new instance, activate the same license key.
|
||||
|
||||
Deactivation reverts the current instance to the Community tier immediately.
|
||||
@@ -3,7 +3,7 @@ title: Multi-Node Management
|
||||
description: Connect multiple Sencho instances and manage all your servers from a single dashboard.
|
||||
---
|
||||
|
||||
Sencho's multi-node feature lets you manage Docker Compose stacks on multiple servers — all from the same browser tab. Each server runs its own Sencho instance, and your primary instance acts as a transparent proxy to the others.
|
||||
Sencho's multi-node feature lets you manage Docker Compose stacks on multiple servers - all from the same browser tab. Each server runs its own Sencho instance, and your primary instance acts as a transparent proxy to the others.
|
||||
|
||||
<Frame>
|
||||
<img src="/images/multi-node/node-manager.png" alt="Node Manager showing a local and a remote node, both Online" />
|
||||
@@ -21,7 +21,7 @@ Your primary Sencho installation is always listed as **Local**. It is the defaul
|
||||
|
||||
### Step 1: Generate a token on the remote machine
|
||||
|
||||
On the **remote** Sencho instance (the server you want to add), open **Settings → Nodes** and click **Generate Token**. Copy the generated token — you'll only see it once.
|
||||
On the **remote** Sencho instance (the server you want to add), open **Settings → Nodes** and click **Generate Token**. Copy the generated token - you'll only see it once.
|
||||
|
||||
<Note>
|
||||
The token is a long-lived JWT scoped to `node_proxy`. Anyone with this token can fully control that Sencho instance, so treat it like a password.
|
||||
@@ -55,7 +55,7 @@ The Compose directory path matters on remote nodes too. When you register a remo
|
||||
|
||||
## Switching between nodes
|
||||
|
||||
The **node switcher** dropdown in the top-left of the sidebar shows the currently active node. Click it to switch to any registered node. All views — dashboard stats, stack list, editor, resources, logs — immediately reflect the selected node.
|
||||
The **node switcher** dropdown in the top-left of the sidebar shows the currently active node. Click it to switch to any registered node. All views - dashboard stats, stack list, editor, resources, logs - immediately reflect the selected node.
|
||||
|
||||
<Frame>
|
||||
<img src="/images/multi-node/node-manager.png" alt="Node switcher dropdown and node list" />
|
||||
@@ -77,4 +77,4 @@ Click the **pencil icon** on any remote node row to edit its name, URL, or token
|
||||
|
||||
- Node tokens grant full control over the remote Sencho instance. Rotate them if compromised via Settings → Nodes → Generate Token (the old token is invalidated).
|
||||
- Use HTTPS between instances in production to prevent token interception.
|
||||
- The host console and container exec terminals are blocked for node-proxy tokens — interactive shell access always requires a real browser session on that instance.
|
||||
- The host console and container exec terminals are blocked for node-proxy tokens - interactive shell access always requires a real browser session on that instance.
|
||||
|
||||
@@ -13,7 +13,7 @@ Full in-browser code editor for your Compose and environment files. Toggle edit
|
||||
|
||||
## Multi-node support
|
||||
|
||||
Add remote Sencho instances as nodes. All dashboard operations — stack management, logs, stats — work identically whether you're targeting your local machine or a server on the other side of the world. Uses a transparent HTTP proxy model; no SSH or shared Docker sockets required. [Learn more →](/features/multi-node)
|
||||
Add remote Sencho instances as nodes. All dashboard operations - stack management, logs, stats - work identically whether you're targeting your local machine or a server on the other side of the world. Uses a transparent HTTP proxy model; no SSH or shared Docker sockets required. [Learn more →](/features/multi-node)
|
||||
|
||||
## Fleet View
|
||||
|
||||
@@ -21,7 +21,7 @@ Monitor your entire infrastructure from a single screen. The fleet dashboard sho
|
||||
|
||||
## RBAC & user management
|
||||
|
||||
Create viewer accounts with read-only access to dashboards, logs, and file contents — while keeping deploy and edit permissions locked to admins. Sencho Pro supports two roles: Admin (full access) and Viewer (read-only). [Learn more →](/features/rbac)
|
||||
Create viewer accounts with read-only access to dashboards, logs, and file contents - while keeping deploy and edit permissions locked to admins. Sencho Pro supports two roles: Admin (full access) and Viewer (read-only). [Learn more →](/features/rbac)
|
||||
|
||||
## Atomic deployments
|
||||
|
||||
@@ -29,7 +29,7 @@ Pro users get automatic backup and rollback on every deployment. Before applying
|
||||
|
||||
## Fleet-wide backups
|
||||
|
||||
Create point-in-time snapshots of every compose file and environment file across all nodes. Snapshots are stored centrally and can be browsed by node and stack. Restore individual stacks from any snapshot with optional one-click redeploy — even to remote nodes. Offline nodes are gracefully skipped with visible warnings. [Learn more →](/features/fleet-backups)
|
||||
Create point-in-time snapshots of every compose file and environment file across all nodes. Snapshots are stored centrally and can be browsed by node and stack. Restore individual stacks from any snapshot with optional one-click redeploy - even to remote nodes. Offline nodes are gracefully skipped with visible warnings. [Learn more →](/features/fleet-backups)
|
||||
|
||||
## Real-time logs & stats
|
||||
|
||||
@@ -57,11 +57,11 @@ Browse 190+ pre-configured application templates. Filter by category (Media, Aut
|
||||
|
||||
## Host console
|
||||
|
||||
Open an interactive terminal on the host OS directly in the browser — full xterm.js emulation with color support. No SSH client required.
|
||||
Open an interactive terminal on the host OS directly in the browser - full xterm.js emulation with color support. No SSH client required.
|
||||
|
||||
## Webhooks
|
||||
|
||||
Trigger stack actions from external CI/CD pipelines via HTTP webhooks. Create a webhook targeting a specific stack and action, then call it from GitHub Actions, GitLab CI, or any system that can send an HTTP POST. Requests are authenticated with HMAC-SHA256 signatures — no session cookies required. [Learn more →](/features/webhooks)
|
||||
Trigger stack actions from external CI/CD pipelines via HTTP webhooks. Create a webhook targeting a specific stack and action, then call it from GitHub Actions, GitLab CI, or any system that can send an HTTP POST. Requests are authenticated with HMAC-SHA256 signatures - no session cookies required. [Learn more →](/features/webhooks)
|
||||
|
||||
## Alerts & notifications
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
---
|
||||
title: RBAC & User Management
|
||||
description: Role-based access control for Sencho Pro — create admin and viewer accounts to control who can modify your stacks.
|
||||
description: Role-based access control for Sencho Pro - create admin and viewer accounts to control who can modify your stacks.
|
||||
---
|
||||
|
||||
<Note>
|
||||
@@ -13,7 +13,7 @@ Sencho Pro introduces role-based access control with two distinct roles: **Admin
|
||||
|
||||
| Role | Description |
|
||||
|------|-------------|
|
||||
| **Admin** | Full access to all features — deploy, edit, manage users, configure nodes, and more |
|
||||
| **Admin** | Full access to all features - deploy, edit, manage users, configure nodes, and more |
|
||||
| **Viewer** | Read-only access to dashboards, logs, stats, and file contents |
|
||||
|
||||
### What viewers can see
|
||||
@@ -23,7 +23,7 @@ Sencho Pro introduces role-based access control with two distinct roles: **Admin
|
||||
- Compose and `.env` file contents (read-only)
|
||||
- Per-container stats and logs
|
||||
- Fleet view
|
||||
- Resources hub (images, volumes, networks — read-only)
|
||||
- Resources hub (images, volumes, networks - read-only)
|
||||
- Global logs
|
||||
- Notifications
|
||||
|
||||
@@ -47,12 +47,12 @@ Admins can manage accounts in **Settings → Users**. From there you can:
|
||||
|
||||
## Migration from single-admin setup
|
||||
|
||||
When you upgrade to Sencho Pro, your existing single-admin credentials are automatically migrated to the new users table. No manual action is required — your login continues to work as before, and your account is assigned the Admin role.
|
||||
When you upgrade to Sencho Pro, your existing single-admin credentials are automatically migrated to the new users table. No manual action is required - your login continues to work as before, and your account is assigned the Admin role.
|
||||
|
||||
## License tiers
|
||||
|
||||
| Tier | Admin accounts | Viewer accounts |
|
||||
|------|---------------|-----------------|
|
||||
| **Community** | 1 | 0 |
|
||||
| **Personal Pro** | 1 | 1 |
|
||||
| **Personal Pro** | 1 | 3 |
|
||||
| **Team Pro** | Unlimited | Unlimited |
|
||||
|
||||
@@ -23,7 +23,7 @@ Click any segment to automatically filter the tabs below to that category.
|
||||
|
||||
## Quick Clean panel
|
||||
|
||||
Four prune buttons let you reclaim disk space immediately. By default they operate on **Sencho-managed resources only** — they will not touch external Docker projects.
|
||||
Four prune buttons let you reclaim disk space immediately. By default they operate on **Sencho-managed resources only** - they will not touch external Docker projects.
|
||||
|
||||
| Button | What it removes |
|
||||
|--------|----------------|
|
||||
@@ -32,7 +32,7 @@ Four prune buttons let you reclaim disk space immediately. By default they opera
|
||||
| **Prune Dead Networks** | Networks not connected to any Sencho container |
|
||||
| **Purge Unmanaged Containers** | Containers Sencho doesn't recognise (started outside it) |
|
||||
|
||||
Each button has a **⋮ More options** menu that lets you target **all Docker resources** instead of Sencho-only. Use this carefully — it can affect other Compose projects running on the same host.
|
||||
Each button has a **⋮ More options** menu that lets you target **all Docker resources** instead of Sencho-only. Use this carefully - it can affect other Compose projects running on the same host.
|
||||
|
||||
A confirmation dialog appears before any destructive operation, showing a summary of what will be removed.
|
||||
|
||||
@@ -45,8 +45,8 @@ Lists all Docker images on the host with their ID, repository tag, size, and sta
|
||||
**Filter buttons:** `All` · `Managed` · `External`
|
||||
|
||||
**Status badges:**
|
||||
- `In Use` + stack name — image is actively used by a running container
|
||||
- `Unused` — image has no running containers; safe to delete
|
||||
- `In Use` + stack name - image is actively used by a running container
|
||||
- `Unused` - image has no running containers; safe to delete
|
||||
|
||||
Click the trash icon on any row to delete an individual image. Sencho will warn you if the image is in use.
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ Click **Create Stack** in the left sidebar. Enter a name and click **Create**.
|
||||
**Naming rules:**
|
||||
- Lowercase letters, numbers, and hyphens only (e.g. `my-app`, `nextcloud`)
|
||||
- No spaces or special characters
|
||||
- Must be unique — duplicates are rejected
|
||||
- Must be unique - duplicates are rejected
|
||||
|
||||
Sencho creates a new directory inside `COMPOSE_DIR` with a blank `compose.yaml` file. You'll land in the editor automatically.
|
||||
|
||||
@@ -34,7 +34,7 @@ Use the **search box** above the list to filter stacks by name.
|
||||
|
||||
## Deploying a stack
|
||||
|
||||
Select a stack and click **Deploy** in the stack header. This runs `docker compose up -d` — pulling images if needed and creating or recreating containers.
|
||||
Select a stack and click **Deploy** in the stack header. This runs `docker compose up -d` - pulling images if needed and creating or recreating containers.
|
||||
|
||||
<Frame>
|
||||
<img src="/images/editor/editor-overview.png" alt="Stack editor with control buttons" />
|
||||
@@ -52,7 +52,7 @@ The stack header exposes four actions:
|
||||
| **Delete** | `down` + removes files | Stops and removes containers, then deletes the stack directory. |
|
||||
|
||||
<Warning>
|
||||
**Delete** is irreversible. It removes the stack directory — including `compose.yaml`, `.env`, and any bind-mounted files stored there. Back up important files before deleting.
|
||||
**Delete** is irreversible. It removes the stack directory - including `compose.yaml`, `.env`, and any bind-mounted files stored there. Back up important files before deleting.
|
||||
</Warning>
|
||||
|
||||
## Stack context menu
|
||||
@@ -63,8 +63,8 @@ Right-click or use the **⋮** button on any stack in the sidebar to access:
|
||||
<img src="/images/stack-management/stack-context-menu.png" alt="Stack context menu showing Alerts option" />
|
||||
</Frame>
|
||||
|
||||
- **Alerts** — configure metric-based alerting rules for this stack
|
||||
- **Check for updates** — manually trigger an image update check
|
||||
- **Alerts** - configure metric-based alerting rules for this stack
|
||||
- **Check for updates** - manually trigger an image update check
|
||||
|
||||
## Converting a `docker run` command
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ description: Trigger stack actions from CI/CD pipelines via HTTP webhooks with H
|
||||
Webhooks require a Sencho Pro license.
|
||||
</Note>
|
||||
|
||||
Sencho webhooks let external systems trigger stack actions over HTTP. The typical use case: your CI pipeline builds a new image, then calls a Sencho webhook to deploy the updated stack — no manual intervention required.
|
||||
Sencho webhooks let external systems trigger stack actions over HTTP. The typical use case: your CI pipeline builds a new image, then calls a Sencho webhook to deploy the updated stack - no manual intervention required.
|
||||
|
||||
## How it works
|
||||
|
||||
@@ -26,7 +26,7 @@ Open **Settings → Webhooks** and click **Create Webhook**. Fill in:
|
||||
| **Stack** | The target stack to act on |
|
||||
| **Action** | One of: `deploy`, `restart`, `stop`, `start`, `pull` |
|
||||
|
||||
After creation, Sencho shows the webhook secret **once**. Copy it immediately — it cannot be retrieved later.
|
||||
After creation, Sencho shows the webhook secret **once**. Copy it immediately - it cannot be retrieved later.
|
||||
|
||||
### Actions explained
|
||||
|
||||
@@ -122,6 +122,6 @@ Each webhook tracks its last 100 executions. Click **Recent executions** on any
|
||||
|
||||
- Webhook secrets are 64-character hex strings generated with `crypto.randomBytes(32)`
|
||||
- Signature validation uses `crypto.timingSafeEqual` to prevent timing attacks
|
||||
- Secrets are shown only once at creation — API responses return masked values
|
||||
- Secrets are shown only once at creation - API responses return masked values
|
||||
- Webhook trigger endpoints are public (no session cookie required) but protected by HMAC signature validation
|
||||
- Each webhook targets a single stack — there is no way to execute arbitrary commands
|
||||
- Each webhook targets a single stack - there is no way to execute arbitrary commands
|
||||
|
||||
@@ -41,21 +41,21 @@ volumes:
|
||||
```
|
||||
|
||||
<Warning>
|
||||
Without a persistent data mount, Sencho will lose all configuration — including registered nodes, alerts, and settings — every time the container restarts.
|
||||
Without a persistent data mount, Sencho will lose all configuration - including registered nodes, alerts, and settings - every time the container restarts.
|
||||
</Warning>
|
||||
|
||||
### Compose directory — the 1:1 path rule
|
||||
### Compose directory - the 1:1 path rule
|
||||
|
||||
<Warning>
|
||||
This is the most common source of deployment problems. Read carefully.
|
||||
</Warning>
|
||||
|
||||
When Sencho runs `docker compose up`, it does so on your **host machine**. Docker resolves relative volume paths in your Compose files relative to the **host** path of the stack directory — not the path inside the Sencho container.
|
||||
When Sencho runs `docker compose up`, it does so on your **host machine**. Docker resolves relative volume paths in your Compose files relative to the **host** path of the stack directory - not the path inside the Sencho container.
|
||||
|
||||
**The rule:** Mount your Compose directory at the **exact same path** inside the container as it exists on your host.
|
||||
|
||||
```yaml
|
||||
# ✅ Correct — host path matches container path
|
||||
# ✅ Correct - host path matches container path
|
||||
volumes:
|
||||
- /home/boris/docker:/home/boris/docker
|
||||
environment:
|
||||
@@ -63,7 +63,7 @@ environment:
|
||||
```
|
||||
|
||||
```yaml
|
||||
# ❌ Wrong — paths differ, relative volumes will break
|
||||
# ❌ Wrong - paths differ, relative volumes will break
|
||||
volumes:
|
||||
- /home/boris/docker:/app/compose
|
||||
environment:
|
||||
@@ -158,4 +158,4 @@ labels:
|
||||
|
||||
## First boot
|
||||
|
||||
After starting Sencho, open it in your browser. If no admin account exists yet, you'll be taken to a setup screen to create one. This only appears once — subsequent visits go directly to the login page.
|
||||
After starting Sencho, open it in your browser. If no admin account exists yet, you'll be taken to a setup screen to create one. This only appears once - subsequent visits go directly to the login page.
|
||||
|
||||
@@ -3,7 +3,7 @@ title: Introduction
|
||||
description: What Sencho is and why you might want it.
|
||||
---
|
||||
|
||||
Sencho is a self-hosted Docker Compose management dashboard. It gives you a clean web UI to deploy, manage, and monitor your Docker Compose stacks — locally or across multiple remote servers — without touching a terminal.
|
||||
Sencho is a self-hosted Docker Compose management dashboard. It gives you a clean web UI to deploy, manage, and monitor your Docker Compose stacks - locally or across multiple remote servers - without touching a terminal.
|
||||
|
||||
<Frame>
|
||||
<img src="/images/dashboard/dashboard-overview.png" alt="Sencho dashboard showing system stats and container metrics" />
|
||||
@@ -11,9 +11,9 @@ Sencho is a self-hosted Docker Compose management dashboard. It gives you a clea
|
||||
|
||||
## Key concepts
|
||||
|
||||
- **Stacks** — a Docker Compose project living in your `COMPOSE_DIR`. Sencho treats each subdirectory as a stack.
|
||||
- **Nodes** — a Sencho instance. Your local machine is always the default node. Add remote nodes by pointing Sencho at another Sencho instance's API URL.
|
||||
- **Resources** — images, volumes, and networks that belong to your stacks (managed) or exist outside them (external/unused).
|
||||
- **Stacks** - a Docker Compose project living in your `COMPOSE_DIR`. Sencho treats each subdirectory as a stack.
|
||||
- **Nodes** - a Sencho instance. Your local machine is always the default node. Add remote nodes by pointing Sencho at another Sencho instance's API URL.
|
||||
- **Resources** - images, volumes, and networks that belong to your stacks (managed) or exist outside them (external/unused).
|
||||
|
||||
<Note>
|
||||
Sencho never accesses remote servers directly via SSH or Docker TCP. Remote management works by proxying API requests to another running Sencho instance.
|
||||
@@ -21,12 +21,12 @@ Sencho is a self-hosted Docker Compose management dashboard. It gives you a clea
|
||||
|
||||
## What you can do
|
||||
|
||||
- **Deploy and control stacks** — create, start, stop, restart, and delete Compose stacks with one click
|
||||
- **Edit files in-browser** — full Monaco editor for `compose.yaml` and `.env` files
|
||||
- **Monitor in real-time** — live CPU, RAM, disk, and network stats with historical charts
|
||||
- **Stream logs** — tail container logs individually or aggregate all stacks in one view
|
||||
- **Manage resources** — browse, filter, and prune Docker images, volumes, and networks
|
||||
- **Deploy from the App Store** — one-click deployment from a curated template registry
|
||||
- **Run a host console** — interactive terminal on the host OS directly in the browser
|
||||
- **Set alerts** — threshold-based notifications via Discord, Slack, or any webhook
|
||||
- **Manage multiple servers** — add remote Sencho instances as nodes and switch between them seamlessly
|
||||
- **Deploy and control stacks** - create, start, stop, restart, and delete Compose stacks with one click
|
||||
- **Edit files in-browser** - full Monaco editor for `compose.yaml` and `.env` files
|
||||
- **Monitor in real-time** - live CPU, RAM, disk, and network stats with historical charts
|
||||
- **Stream logs** - tail container logs individually or aggregate all stacks in one view
|
||||
- **Manage resources** - browse, filter, and prune Docker images, volumes, and networks
|
||||
- **Deploy from the App Store** - one-click deployment from a curated template registry
|
||||
- **Run a host console** - interactive terminal on the host OS directly in the browser
|
||||
- **Set alerts** - threshold-based notifications via Discord, Slack, or any webhook
|
||||
- **Manage multiple servers** - add remote Sencho instances as nodes and switch between them seamlessly
|
||||
|
||||
@@ -29,10 +29,10 @@ Open `http://localhost:3000` in your browser. On first boot you'll be prompted t
|
||||
|
||||
## Important: the 1:1 path rule
|
||||
|
||||
The `-v /opt/compose:/app/compose` mount above uses a simplified path for illustration. In practice, you must mount your compose directory at the **same path** inside and outside the container. See the [Configuration guide](/getting-started/configuration#compose-directory-the-11-path-rule) for details — this is the most common setup mistake.
|
||||
The `-v /opt/compose:/app/compose` mount above uses a simplified path for illustration. In practice, you must mount your compose directory at the **same path** inside and outside the container. See the [Configuration guide](/getting-started/configuration#compose-directory-the-11-path-rule) for details - this is the most common setup mistake.
|
||||
|
||||
## Next steps
|
||||
|
||||
- [Configuration](/getting-started/configuration) — full environment variable reference, reverse proxy setup
|
||||
- [Stack Management](/features/stack-management) — create and deploy your first stack
|
||||
- [Multi-Node](/features/multi-node) — add a remote server to manage from this dashboard
|
||||
- [Configuration](/getting-started/configuration) - full environment variable reference, reverse proxy setup
|
||||
- [Stack Management](/features/stack-management) - create and deploy your first stack
|
||||
- [Multi-Node](/features/multi-node) - add a remote server to manage from this dashboard
|
||||
|
||||
@@ -14,13 +14,13 @@ Sencho stores all its state in two places: the **data directory** (SQLite databa
|
||||
Default path: `/app/data` inside the container, mapped to wherever you mounted it on the host (e.g. `./sencho-data`).
|
||||
|
||||
Contains:
|
||||
- `sencho.db` — SQLite database with all settings, nodes, alerts, metrics history, and notification history
|
||||
- `sencho.db` - SQLite database with all settings, nodes, alerts, metrics history, and notification history
|
||||
|
||||
This single file is everything Sencho knows about itself. Back it up and you can fully restore any Sencho installation.
|
||||
|
||||
### 2. Compose directory (`COMPOSE_DIR`)
|
||||
|
||||
The directory containing your stack subdirectories — your `compose.yaml` files, `.env` files, and any bind-mounted config files stored there.
|
||||
The directory containing your stack subdirectories - your `compose.yaml` files, `.env` files, and any bind-mounted config files stored there.
|
||||
|
||||
This is your actual application data. It lives entirely outside Sencho and you almost certainly already have it on a schedule, but include it in any Sencho backup plan.
|
||||
|
||||
@@ -131,7 +131,7 @@ If other Sencho instances were pointing to your old host as a remote node, updat
|
||||
| Item | Location | Notes |
|
||||
|------|----------|-------|
|
||||
| Container data volumes | Wherever each stack's volumes are mounted on the host | Back these up separately per-application |
|
||||
| Actual container images | Docker image cache | These are re-pulled on next deploy — no backup needed |
|
||||
| Actual container images | Docker image cache | These are re-pulled on next deploy - no backup needed |
|
||||
| Sencho logs (docker logs) | Container stdout | Not persisted beyond container lifetime |
|
||||
|
||||
<Note>
|
||||
|
||||
@@ -15,13 +15,13 @@ docker compose -f /path/to/your/stack/compose.yaml logs
|
||||
|
||||
The most common causes:
|
||||
|
||||
- **Missing environment variable** — a required variable in your `.env` file is empty or has the wrong name.
|
||||
- **Port already in use** — another container or host process is bound to the same port. Change the host port in the compose file.
|
||||
- **Volume path does not exist** — a bind-mount path on the host doesn't exist yet. Create the directory manually.
|
||||
- **Missing environment variable** - a required variable in your `.env` file is empty or has the wrong name.
|
||||
- **Port already in use** - another container or host process is bound to the same port. Change the host port in the compose file.
|
||||
- **Volume path does not exist** - a bind-mount path on the host doesn't exist yet. Create the directory manually.
|
||||
|
||||
---
|
||||
|
||||
## The 1:1 path rule — volumes resolve to wrong paths
|
||||
## The 1:1 path rule - volumes resolve to wrong paths
|
||||
|
||||
**Symptom:** Stacks deploy but relative volume paths (e.g. `./config:/config`) point to the wrong location inside the container, or `docker compose` exits with a path error.
|
||||
|
||||
@@ -37,7 +37,7 @@ environment:
|
||||
- COMPOSE_DIR=/opt/docker
|
||||
```
|
||||
|
||||
See [Configuration — the 1:1 path rule](/getting-started/configuration#compose-directory-the-11-path-rule) for a full explanation.
|
||||
See [Configuration - the 1:1 path rule](/getting-started/configuration#compose-directory-the-11-path-rule) for a full explanation.
|
||||
|
||||
---
|
||||
|
||||
@@ -61,7 +61,7 @@ ls -la /var/run/docker.sock
|
||||
# Expected: srw-rw---- 1 root docker ...
|
||||
```
|
||||
|
||||
If the group is not `docker`, the auto-detection still works — Sencho reads the GID from the socket file at startup.
|
||||
If the group is not `docker`, the auto-detection still works - Sencho reads the GID from the socket file at startup.
|
||||
|
||||
---
|
||||
|
||||
@@ -95,7 +95,7 @@ proxy_set_header Connection "upgrade";
|
||||
proxy_read_timeout 3600s;
|
||||
```
|
||||
|
||||
Traefik handles WebSocket upgrades automatically for HTTP/1.1 backends — no extra config needed.
|
||||
Traefik handles WebSocket upgrades automatically for HTTP/1.1 backends - no extra config needed.
|
||||
|
||||
---
|
||||
|
||||
@@ -106,7 +106,7 @@ Traefik handles WebSocket upgrades automatically for HTTP/1.1 backends — no ex
|
||||
**Checks in order:**
|
||||
|
||||
1. **Is the remote Sencho instance running?** SSH to that machine and verify.
|
||||
2. **Is the API URL correct?** It must include the protocol and port (e.g. `http://192.168.1.20:3001`). Open it in a browser — you should see a JSON response from `/api/health`.
|
||||
2. **Is the API URL correct?** It must include the protocol and port (e.g. `http://192.168.1.20:3001`). Open it in a browser - you should see a JSON response from `/api/health`.
|
||||
3. **Is the token correct?** Tokens are long JWT strings. Even one missing character will cause auth to fail. Regenerate the token on the remote instance and update the node config.
|
||||
4. **Is there a firewall blocking the port?** The primary Sencho host must be able to reach the remote host's Sencho port.
|
||||
|
||||
@@ -131,7 +131,7 @@ sqlite3 /path/to/data/sencho.db
|
||||
DELETE FROM global_settings WHERE key IN ('auth_username', 'auth_password_hash', 'auth_jwt_secret');
|
||||
```
|
||||
|
||||
4. Restart the container — the setup screen will appear on next visit.
|
||||
4. Restart the container - the setup screen will appear on next visit.
|
||||
|
||||
<Warning>
|
||||
This resets authentication entirely. All active sessions become invalid. Your stacks, nodes, and alert rules are not affected.
|
||||
|
||||
@@ -31,7 +31,7 @@ Click **Update Password** to apply. The change takes effect immediately; existin
|
||||
|
||||
**Scope:** Per-node (applies to the currently selected node)
|
||||
|
||||
Configure resource thresholds that trigger visual warnings on the dashboard stat cards. These are display thresholds only — Sencho does not throttle or kill containers when limits are reached.
|
||||
Configure resource thresholds that trigger visual warnings on the dashboard stat cards. These are display thresholds only - Sencho does not throttle or kill containers when limits are reached.
|
||||
|
||||
| Setting | Range | Description |
|
||||
|---------|-------|-------------|
|
||||
@@ -99,7 +99,7 @@ Click **Save** to apply.
|
||||
|
||||
**Scope:** Global
|
||||
|
||||
Manage connections to local and remote Sencho instances. This is the same interface as the [Multi-Node](/features/multi-node) feature — see that page for the full walkthrough.
|
||||
Manage connections to local and remote Sencho instances. This is the same interface as the [Multi-Node](/features/multi-node) feature - see that page for the full walkthrough.
|
||||
|
||||
Quick reference:
|
||||
|
||||
|
||||
Reference in New Issue
Block a user