docs: bootstrap user-facing documentation from codebase audit

- Add 5 new Tier 1 doc pages: configuration, stack-management, editor,
  multi-node, and alerts-notifications
- Update introduction, quickstart, and features/overview to reflect
  current feature set and link to new pages
- Restructure mint.json with Getting Started / Features / Reference /
  Operations navigation groups
- Add Playwright-captured screenshots for all major UI screens
This commit is contained in:
SaelixCode
2026-03-22 22:39:06 -04:00
parent dfa93c0bba
commit 98910c4117
21 changed files with 532 additions and 10 deletions
+1
View File
@@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Added
- feat: automated documentation pipeline with Mintlify sync
- feat: CI job to auto-refresh doc screenshots on every develop push
- docs: bootstrap user-facing documentation from codebase audit — added configuration, stack management, editor, multi-node, and alerts & notifications pages; updated introduction, quickstart, and features overview; restructured mint.json navigation with Getting Started / Features / Reference / Operations groups
### Fixed
- fix(ci): YAML syntax error in update-screenshots `if:` condition (`!` tag and `: ` in plain scalar); wrapped in `${{ }}`
+95
View File
@@ -0,0 +1,95 @@
---
title: Alerts & Notifications
description: Set threshold-based alerts on container metrics and route them to Discord, Slack, or any webhook.
---
Sencho can watch your containers for resource anomalies and notify you when thresholds are breached. Alerts are defined per stack, and notifications are delivered through external agents you configure.
<Frame>
<img src="/images/alerts-notifications/notifications-settings.png" alt="Notifications & Alerts settings showing Discord, Slack, and Webhook tabs" />
</Frame>
## How alerts work
Sencho's monitoring service samples container metrics every minute and evaluates all defined alert rules. When a rule's condition holds true for the configured duration, a notification is dispatched. A cooldown period prevents the same alert from firing repeatedly.
## Setting up a notification agent
At least one agent must be enabled before alerts can be delivered. Go to **Settings → Notifications**.
### Discord
1. In Discord, go to your server's **Settings → Integrations → Webhooks**
2. Click **New Webhook**, choose a channel, and copy the webhook URL
3. In Sencho, open **Settings → Notifications → Discord**, paste the URL, enable the toggle, and click **Save**
4. Click **Test** to send a test message
### Slack
1. In Slack, go to **api.slack.com/apps**, create an app, and add the **Incoming Webhooks** feature
2. Activate it and copy the generated webhook URL for your chosen channel
3. In Sencho, open **Settings → Notifications → Slack**, paste the URL, enable the toggle, and click **Save**
### Generic Webhook
Any HTTP endpoint that accepts a POST with a JSON body can receive Sencho alerts. Go to **Settings → Notifications → Webhook**, enter the URL, and click **Save**.
The payload format is:
```json
{
"level": "warning",
"message": "cpu_percent exceeded 90% for 5 minutes on stack my-app",
"timestamp": "2026-03-22T10:00:00.000Z"
}
```
## Creating stack alerts
Stack alerts are configured per-stack. Right-click a stack in the sidebar (or click the **⋮** button) and select **Alerts**.
<Frame>
<img src="/images/stack-management/stack-context-menu.png" alt="Stack context menu showing the Alerts option" />
</Frame>
The alerts sheet shows existing rules for the stack and a form to create new ones.
### Alert fields
| Field | Description |
|-------|-------------|
| **Metric** | The container metric to watch |
| **Operator** | Comparison operator: `>`, `>=`, `<`, `<=`, `==` |
| **Threshold** | The value to compare against |
| **Duration (minutes)** | How long the condition must hold before firing |
| **Cooldown (minutes)** | Minimum time between repeated notifications for this rule |
### Available metrics
| Metric | Unit | Description |
|--------|------|-------------|
| `cpu_percent` | % | CPU usage relative to total host cores |
| `memory_mb` | MB | RSS memory used by the container |
| `memory_percent` | % | Memory used as a fraction of the host total |
| `net_rx` | bytes/s | Inbound network rate |
| `net_tx` | bytes/s | Outbound network rate |
| `restart_count` | count | Number of times the container has restarted |
### Example: alert on high CPU
To alert when any container in a stack uses more than 80% CPU for over 5 consecutive minutes, with a 30-minute cooldown:
| Field | Value |
|-------|-------|
| Metric | `cpu_percent` |
| Operator | `>` |
| Threshold | `80` |
| Duration | `5` |
| Cooldown | `30` |
## Notification history
All dispatched notifications appear in the **notification bell** (top-right of the nav bar). Click it to see recent alerts with their level, message, and timestamp. Mark all as read or clear individual entries from there.
<Note>
Notifications only reach external agents (Discord, Slack, Webhook) if at least one agent is enabled. Dashboard notifications appear regardless.
</Note>
+64
View File
@@ -0,0 +1,64 @@
---
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.
<Frame>
<img src="/images/editor/editor-overview.png" alt="Editor view showing container panel and Monaco editor" />
</Frame>
## Compose file editor
The right panel shows your `compose.yaml` with full syntax highlighting. By default the editor is **read-only** to prevent accidental changes.
Click **Edit** to enter edit mode. Your changes are unsaved until you explicitly save them.
### Save options
| Button | What it does |
|--------|--------------|
| **Save** | Writes the file to disk. Does not restart any containers. |
| **Save & Deploy** | Writes the file, then immediately runs `docker compose up -d`. Use this to apply compose changes in one step. |
| **Discard** | Reverts the editor to the last saved version. Unsaved changes are lost. |
## Environment file editor
Click the **.env** tab to switch to the environment file editor. If your `compose.yaml` references multiple env files (via `env_file:`), a dropdown lets you select which file to edit.
The `.env` editor has the same save/discard controls as the compose editor. Changes take effect the next time the stack is deployed.
<Note>
Sencho reads the `env_file:` paths from your `compose.yaml` to discover available env files. If no `env_file:` is declared, a default `.env` in the stack directory is used.
</Note>
## Container panel
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 12 seconds
- **Port mappings** — host:container port pairs (if any)
### Container actions
Each container row has three action buttons:
| Button | What it does |
|--------|--------------|
| **Logs** (external link icon) | Opens a live log stream modal for that container |
| **Terminal** (terminal icon) | Opens an interactive bash session inside the container |
| **Copy ID** | Copies the container ID to the clipboard |
### Log viewer
The log viewer streams output from a single container in real-time using Server-Sent Events. Logs auto-scroll to the bottom as new lines arrive. Close the modal to stop the stream.
### 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.
<Warning>
The container terminal requires the container to have `bash` (or `sh`) installed. Minimal images (e.g. Alpine-based) may need `sh` instead.
</Warning>
+80
View File
@@ -0,0 +1,80 @@
---
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.
<Frame>
<img src="/images/multi-node/node-manager.png" alt="Node Manager showing a local and a remote node, both Online" />
</Frame>
## How it works
There is no central server. Each Sencho instance manages its own host independently. When you select a remote node, your browser's API calls are proxied through your local Sencho instance to the remote one, authenticated by a long-lived Bearer token. No SSH. No shared Docker sockets.
## The local node
Your primary Sencho installation is always listed as **Local**. It is the default node, marked with a star, and cannot be deleted. All operations on the local node run directly against the host's Docker socket.
## Adding a remote node
### 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.
<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.
</Note>
### Step 2: Add the node on your primary instance
On your **primary** Sencho instance, open **Settings → Nodes** and click **+ Add Node**. Fill in:
| Field | Description |
|-------|-------------|
| **Name** | A display name (e.g. `prod-server`, `media-box`) |
| **Type** | Select **Remote** |
| **Sencho API URL** | The full HTTP/HTTPS URL of the remote instance (e.g. `http://192.168.1.20:3001`) |
| **API Token** | The token you generated in Step 1 |
Click **Create**. Sencho immediately tests the connection and shows the result.
### Step 3: Verify connectivity
A successful connection shows the remote node as **Online** with a green badge. If it shows **Offline** or **Unknown**, check:
- The remote Sencho instance is running and reachable from your primary host
- The API URL is correct (include the port if non-standard)
- The token was copied correctly without extra whitespace
Click the **wifi icon** (test connection) on any node row at any time to re-check status.
## The 1:1 path rule for remote nodes
The Compose directory path matters on remote nodes too. When you register a remote node, its `COMPOSE_DIR` is whatever that remote instance was configured with. Make sure the remote Sencho's `COMPOSE_DIR` follows the [1:1 path rule](/getting-started/configuration#compose-directory-the-11-path-rule) on that remote host.
## 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.
<Frame>
<img src="/images/multi-node/node-manager.png" alt="Node switcher dropdown and node list" />
</Frame>
Node status indicators:
| Indicator | Meaning |
|-----------|---------|
| Green dot | Node is reachable and responding |
| Red dot | Node is unreachable |
| Gray dot | Status not yet checked |
## Editing and deleting nodes
Click the **pencil icon** on any remote node row to edit its name, URL, or token. Click the **trash icon** to remove it. The local node cannot be edited or deleted.
## Security considerations
- 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.
+22 -6
View File
@@ -5,15 +5,23 @@ description: A high-level tour of everything Sencho can do.
## Stack management
Deploy, start, stop, restart, and remove Docker Compose stacks through a point-and-click interface. Edit `docker-compose.yml` files directly in the built-in Monaco editor.
Deploy, start, stop, restart, and remove Docker Compose stacks through a point-and-click interface. Edit `compose.yaml` and `.env` files directly in the built-in Monaco editor with syntax highlighting. [Learn more →](/features/stack-management)
## Editor
Full in-browser code editor for your Compose and environment files. Toggle edit mode, save to disk, or save and deploy in one step. Per-container live stats and an interactive bash exec terminal live alongside the editor. [Learn more →](/features/editor)
## 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.
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)
## Real-time logs & stats
Stream container logs and resource metrics (CPU, memory, network I/O) live in the browser via WebSocket connections.
Stream container logs and resource metrics (CPU, memory, network I/O) live in the browser via WebSocket and Server-Sent Events connections. The Home dashboard shows historical CPU and RAM charts over the last 24 hours.
## Global observability
The **Logs** view aggregates output from all containers across all stacks into a single scrollable stream. Filter by stack, log level (stdout/stderr), or search for keywords. Switch to developer mode for real-time SSE streaming.
## Resources hub
@@ -23,10 +31,18 @@ View and manage all Docker images, volumes, and networks. Resources are classifi
|-------|---------|
| **Managed** | Owned by a Sencho stack |
| **External** | Part of another Compose project |
| **Unused / System** | Reclaimable or Docker-internal |
| **Unused / Reclaimable** | Safe to prune |
Run scoped prune operations to clean up Sencho-managed resources only, or target all Docker resources when needed.
## Notifications & alerts
## App Store
Configure threshold-based alerts for CPU and memory usage. Notifications surface in the dashboard and can be dismissed or cleared in bulk.
Browse 190+ pre-configured application templates. Filter by category (Media, Automation, Development, etc.), configure environment variables, volumes, and ports, and deploy with a single click.
## 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.
## Alerts & notifications
Configure threshold-based alerts (CPU, memory, network, restart count) per stack. Route notifications to Discord, Slack, or any generic webhook endpoint. [Learn more →](/features/alerts-notifications)
+71
View File
@@ -0,0 +1,71 @@
---
title: Stack Management
description: Create, deploy, control, and remove Docker Compose stacks.
---
A **stack** in Sencho is a Docker Compose project: a directory inside your `COMPOSE_DIR` that contains at least a `compose.yaml` (or `docker-compose.yml`) file. Sencho automatically discovers every subdirectory as a stack.
<Frame>
<img src="/images/stack-management/create-stack-dialog.png" alt="Create New Stack dialog" />
</Frame>
## Creating a stack
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
Sencho creates a new directory inside `COMPOSE_DIR` with a blank `compose.yaml` file. You'll land in the editor automatically.
## The stack list
All discovered stacks appear in the left sidebar. Each shows a color-coded status dot:
| Color | Meaning |
|-------|---------|
| Green | All containers running |
| Red | One or more containers exited |
| Gray | No containers / status unknown |
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.
<Frame>
<img src="/images/editor/editor-overview.png" alt="Stack editor with control buttons" />
</Frame>
## Controlling a running stack
The stack header exposes four actions:
| Button | Command | What it does |
|--------|---------|--------------|
| **Stop** | `docker compose stop` | Stops containers without removing them. State is preserved. |
| **Restart** | `docker compose restart` | Restarts all containers in the stack. |
| **Update** | `docker compose pull` + `up -d` | Pulls the latest image tags and recreates containers. |
| **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.
</Warning>
## Stack context menu
Right-click or use the **⋮** button on any stack in the sidebar to access:
<Frame>
<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
## Converting a `docker run` command
If you have an existing `docker run` command and want to turn it into a Compose stack, go to the **Home** tab and paste it into the "Convert Docker Run to Compose" field. Sencho converts it to YAML that you can save as a new stack.
+161
View File
@@ -0,0 +1,161 @@
---
title: Configuration
description: Environment variables, volume mounts, and the 1:1 path rule.
---
Sencho is configured entirely through environment variables and Docker volume mounts. There is no config file to edit inside the container.
## Required environment variables
| Variable | Description |
|----------|-------------|
| `JWT_SECRET` | Secret key used to sign session tokens. Use a long, random string (32+ characters). Changing this invalidates all active sessions. |
| `COMPOSE_DIR` | Absolute path to the directory that contains your Compose stacks. Every subdirectory inside becomes a stack in Sencho. |
## Optional environment variables
| Variable | Default | Description |
|----------|---------|-------------|
| `PORT` | `3000` | Port the Sencho HTTP server listens on. |
| `DATA_DIR` | `/app/data` | Directory where Sencho stores its SQLite database, node registry, and cached metrics. |
| `NODE_ENV` | `production` | Set automatically in the Docker image. Only change this for local development. |
## Required volume mounts
### Docker socket
Sencho needs access to the Docker daemon to manage containers:
```yaml
volumes:
- /var/run/docker.sock:/var/run/docker.sock
```
### Data directory
Sencho's database persists all your settings, nodes, alerts, and metrics history. Mount a named volume or host path so it survives container restarts:
```yaml
volumes:
- ./sencho-data:/app/data
```
<Warning>
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
<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.
**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
volumes:
- /home/boris/docker:/home/boris/docker
environment:
- COMPOSE_DIR=/home/boris/docker
```
```yaml
# ❌ Wrong — paths differ, relative volumes will break
volumes:
- /home/boris/docker:/app/compose
environment:
- COMPOSE_DIR=/app/compose
```
If you use a simple path like `/opt/compose` on your host, mount it at `/opt/compose` in the container:
```yaml
volumes:
- /opt/compose:/opt/compose
environment:
- COMPOSE_DIR=/opt/compose
```
## Full docker-compose.yml example
```yaml
services:
sencho:
image: saelix/sencho:latest
restart: unless-stopped
ports:
- "3000:3000"
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- ./sencho-data:/app/data
- /opt/compose:/opt/compose # 1:1 path rule
environment:
- JWT_SECRET=your-long-random-secret-here
- COMPOSE_DIR=/opt/compose
- DATA_DIR=/app/data
```
## Optional: global environment file
If your Compose stacks share common variables (e.g. `PUID`, `PGID`, `TZ`), you can pass an `env_file` to the Sencho container so those variables are available in the host environment when `docker compose` runs:
```yaml
services:
sencho:
image: saelix/sencho:latest
env_file:
- /opt/compose/globals.env # shared vars for all stacks
environment:
- JWT_SECRET=your-secret
- COMPOSE_DIR=/opt/compose
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- /opt/compose:/opt/compose
- ./sencho-data:/app/data
```
## Reverse proxy setup
Sencho works behind any reverse proxy. The only requirement is that WebSocket connections are forwarded correctly (used for live logs, container terminals, and the host console).
### Nginx
```nginx
server {
listen 80;
server_name sencho.yourdomain.com;
location / {
proxy_pass http://localhost:3000;
proxy_http_version 1.1;
# WebSocket support
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_read_timeout 3600s;
}
}
```
### Traefik (Docker labels)
```yaml
labels:
- "traefik.enable=true"
- "traefik.http.routers.sencho.rule=Host(`sencho.yourdomain.com`)"
- "traefik.http.services.sencho.loadbalancer.server.port=3000"
```
<Note>
Traefik handles WebSocket upgrades automatically for HTTP/1.1 backends. No extra configuration needed.
</Note>
## 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.
+16
View File
@@ -5,6 +5,10 @@ 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.
<Frame>
<img src="/images/dashboard/dashboard-overview.png" alt="Sencho dashboard showing system stats and container metrics" />
</Frame>
## Key concepts
- **Stacks** — a Docker Compose project living in your `COMPOSE_DIR`. Sencho treats each subdirectory as a stack.
@@ -14,3 +18,15 @@ Sencho is a self-hosted Docker Compose management dashboard. It gives you a clea
<Note>
Sencho never accesses remote servers directly via SSH or Docker TCP. Remote management works by proxying API requests to another running Sencho instance.
</Note>
## 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
+7 -2
View File
@@ -27,7 +27,12 @@ Open `http://localhost:3000` in your browser. On first boot you'll be prompted t
Replace `/opt/compose` with the path to your Compose projects directory. Every subdirectory inside it becomes a stack in Sencho.
</Note>
## 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.
## Next steps
- [Add a remote node](/features/overview) to manage another server from the same dashboard
- Browse your stacks, start/stop services, and tail logs from the 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
Binary file not shown.

After

Width:  |  Height:  |  Size: 79 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 108 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 87 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 89 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 243 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 97 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 109 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 79 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 187 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 257 KiB

+15 -2
View File
@@ -16,14 +16,27 @@
"group": "Getting Started",
"pages": [
"getting-started/introduction",
"getting-started/quickstart"
"getting-started/quickstart",
"getting-started/configuration"
]
},
{
"group": "Features",
"pages": [
"features/overview"
"features/overview",
"features/stack-management",
"features/editor",
"features/multi-node",
"features/alerts-notifications"
]
},
{
"group": "Reference",
"pages": []
},
{
"group": "Operations",
"pages": []
}
]
}