mirror of
https://github.com/Studio-Saelix/sencho.git
synced 2026-08-10 18:56:53 +00:00
docs: remediate documentation gaps across quickstart, backup, config, API spec, and operations guides (#330)
- Fix Cyrillic character in quickstart image ref and correct registry to Docker Hub (saelix/sencho) - Correct backup guide WAL references (Sencho uses SQLite default journal mode) - Add SSL/TLS reverse proxy examples for Nginx, Traefik, and new Caddy configuration - Add missing env vars (PORT, DATA_DIR, NODE_ENV, FRONTEND_URL, SSO_LDAP_DISPLAY_NAME) to .env.example - Add upgrade & migration guide documenting automatic schema migrations - Add self-hosting best practices (1:1 path rule, Docker socket security, resource recs) - Add architecture overview (system design, request flow, database schema, multi-node model) - Add development & contributor guide (setup, tests, code style, PR workflow) - Update OpenAPI spec from v0.23.0 to v0.25.3 with Registries and Image Updates endpoints - Update docs.json navigation with all new pages and API groups
This commit is contained in:
@@ -0,0 +1,105 @@
|
||||
---
|
||||
title: Architecture Overview
|
||||
description: System design, request flow, database schema, and deployment model.
|
||||
---
|
||||
|
||||
## System overview
|
||||
|
||||
Sencho is a self-contained application packaged as a single Docker container:
|
||||
|
||||
- **Frontend:** React 19 single-page application built with Vite and served as static files
|
||||
- **Backend:** Express.js (Node.js 22) REST API with WebSocket support
|
||||
- **Database:** SQLite via `better-sqlite3` — no external database required
|
||||
- **Container management:** Docker Engine API via the mounted Docker socket, plus Docker Compose CLI for stack operations
|
||||
|
||||
There are no external dependencies. No Redis, no PostgreSQL, no message queues. All state lives in a single SQLite file (`sencho.db`) inside the data directory.
|
||||
|
||||
---
|
||||
|
||||
## Request flow
|
||||
|
||||
### Browser sessions
|
||||
|
||||
1. The browser loads the React SPA from the Express static file server
|
||||
2. The frontend makes API calls via an `apiFetch` wrapper that injects the active node ID as an `x-node-id` header
|
||||
3. Express middleware evaluates the node ID:
|
||||
- **Local node:** The request passes through authentication middleware and hits the local route handler, which communicates with Docker via the mounted socket
|
||||
- **Remote node:** The request is transparently proxied to the remote Sencho instance using `http-proxy-middleware`. The backend strips the `x-node-id` header and injects `Authorization: Bearer <token>` for the remote node
|
||||
4. The response flows back through the same path to the browser
|
||||
|
||||
### API token access
|
||||
|
||||
External integrations (CI/CD pipelines, scripts) authenticate with Bearer tokens instead of cookies. The same route handlers process both authentication methods — the middleware accepts JWT tokens from either cookies or the `Authorization` header.
|
||||
|
||||
---
|
||||
|
||||
## Authentication model
|
||||
|
||||
| Method | Used by | Token storage |
|
||||
|--------|---------|--------------|
|
||||
| HTTP-only cookie (JWT) | Browser sessions | Set by Express on login, sent automatically |
|
||||
| Bearer token (JWT) | API integrations, node-to-node proxy | Passed in `Authorization` header |
|
||||
|
||||
API tokens have scopes that restrict their access: `read-only`, `deploy-only`, or `full-admin`. Tokens are hashed before storage.
|
||||
|
||||
SSO is supported via LDAP, Google OIDC, GitHub OAuth, and Okta OIDC. SSO users are mapped to local accounts on first login.
|
||||
|
||||
---
|
||||
|
||||
## Database
|
||||
|
||||
Sencho stores all state in a single SQLite database using the default journal mode (DELETE/ROLLBACK). The schema includes approximately 20 tables:
|
||||
|
||||
| Table group | Tables | Purpose |
|
||||
|-------------|--------|---------|
|
||||
| **Identity** | `users`, `role_assignments`, `sso_config` | User accounts, RBAC, SSO provider configs |
|
||||
| **Nodes** | `nodes` | Local and remote node connection details |
|
||||
| **Configuration** | `global_settings` | Key-value application settings |
|
||||
| **Automation** | `webhooks`, `webhook_executions`, `scheduled_tasks`, `scheduled_task_runs` | Webhook definitions/history, cron tasks |
|
||||
| **Monitoring** | `stack_alerts`, `notification_history`, `container_metrics`, `agents` | Alert rules, notifications, time-series metrics, notification channels |
|
||||
| **Fleet** | `fleet_snapshots`, `fleet_snapshot_files` | Multi-node backup snapshots |
|
||||
| **Security** | `api_tokens`, `audit_log` | API token hashes, action audit trail |
|
||||
| **Updates** | `stack_update_status` | Image update availability tracking |
|
||||
| **Registries** | Stored via `RegistryService` | Private container registry credentials (encrypted at rest) |
|
||||
| **State** | `system_state` | Internal application state |
|
||||
|
||||
All schema migrations run automatically on startup. See [Upgrading Sencho](/operations/upgrade#automatic-migrations) for details.
|
||||
|
||||
---
|
||||
|
||||
## Multi-node architecture
|
||||
|
||||
Sencho uses a **Distributed API** model for managing multiple hosts:
|
||||
|
||||
- **Local node:** Communicates directly with the Docker Engine via the mounted socket (`/var/run/docker.sock`)
|
||||
- **Remote nodes:** Each remote host runs its own independent Sencho instance. The primary instance acts as a transparent HTTP proxy, routing requests to remote instances using stored API URLs and long-lived JWT tokens
|
||||
|
||||
This means:
|
||||
- No SSH, SFTP, or remote Docker TCP socket connections
|
||||
- Each node is fully autonomous and can operate independently
|
||||
- The primary instance proxies both HTTP requests and WebSocket connections
|
||||
- Node routing is controlled via the `x-node-id` request header (HTTP) or `?nodeId=` query parameter (WebSocket)
|
||||
|
||||
---
|
||||
|
||||
## WebSocket channels
|
||||
|
||||
| Path | Purpose | Auth |
|
||||
|------|---------|------|
|
||||
| `/api/stacks/{stackName}/logs` | Live container log streaming | Cookie or query param token |
|
||||
| `/ws` | Host console terminal (PTY) | Cookie-based, admin only |
|
||||
|
||||
WebSocket connections bypass Express middleware. Authentication is handled manually by parsing cookies and verifying JWTs inside the `upgrade` event handler.
|
||||
|
||||
---
|
||||
|
||||
## Build and deployment
|
||||
|
||||
The Docker image uses a multi-stage build:
|
||||
|
||||
1. **Frontend build stage** — Compiles the React SPA with Vite
|
||||
2. **Backend build stage** — Compiles TypeScript to JavaScript
|
||||
3. **Native module stage** — Cross-compiles native dependencies (`bcrypt`, `better-sqlite3`, `node-pty`) for the target architecture
|
||||
4. **Production stage** — Alpine-based Node.js 22 runtime with Docker CLI and Docker Compose installed
|
||||
|
||||
The final image supports both `linux/amd64` and `linux/arm64` architectures and is published to [Docker Hub](https://hub.docker.com/r/saelix/sencho) as `saelix/sencho`.
|
||||
@@ -0,0 +1,136 @@
|
||||
---
|
||||
title: Development Guide
|
||||
description: Set up a local development environment and contribute to Sencho.
|
||||
---
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- **Node.js 22** or later
|
||||
- **Docker** and **Docker Compose** installed and running
|
||||
- **Git**
|
||||
|
||||
---
|
||||
|
||||
## Setup
|
||||
|
||||
```bash
|
||||
# Clone the repository
|
||||
git clone https://github.com/AnsoCode/Sencho.git
|
||||
cd Sencho
|
||||
|
||||
# Install backend dependencies
|
||||
cd backend && npm install
|
||||
|
||||
# Install frontend dependencies
|
||||
cd ../frontend && npm install
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Running in development
|
||||
|
||||
Open two terminal windows:
|
||||
|
||||
**Terminal 1 — Backend** (Express + nodemon, port 3000):
|
||||
|
||||
```bash
|
||||
cd backend
|
||||
npm run dev
|
||||
```
|
||||
|
||||
**Terminal 2 — Frontend** (Vite dev server, port 5173):
|
||||
|
||||
```bash
|
||||
cd frontend
|
||||
npm run dev
|
||||
```
|
||||
|
||||
The Vite dev server proxies all `/api` and `/ws` requests to `localhost:3000`, so you access the app at `http://localhost:5173`.
|
||||
|
||||
On first boot, you'll see a setup screen to create an admin account.
|
||||
|
||||
<Note>
|
||||
The backend requires a Docker socket to be available. On macOS and Linux this is `/var/run/docker.sock`. On Windows, ensure Docker Desktop is running.
|
||||
</Note>
|
||||
|
||||
---
|
||||
|
||||
## Running tests
|
||||
|
||||
### Backend unit tests (Vitest)
|
||||
|
||||
```bash
|
||||
cd backend
|
||||
npm test
|
||||
```
|
||||
|
||||
Runs all test files in `src/__tests__/`. Each test file runs in an isolated forked process with its own database instance.
|
||||
|
||||
### End-to-end tests (Playwright)
|
||||
|
||||
```bash
|
||||
# From the project root
|
||||
npm run test:e2e
|
||||
```
|
||||
|
||||
E2E tests run against a live development instance (backend on port 3000, frontend on port 5173). Make sure both are running before executing tests.
|
||||
|
||||
For interactive test debugging:
|
||||
|
||||
```bash
|
||||
npm run test:e2e:ui
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Code style
|
||||
|
||||
- **TypeScript** with `strict: true` in both packages. No `any` casts or `@ts-ignore`.
|
||||
- **ESLint 9** flat config. Run `npm run lint` in both `backend/` and `frontend/` directories.
|
||||
- **Frontend styling:** Tailwind CSS with [shadcn/ui](https://ui.shadcn.com/) components. See the design system section in `CLAUDE.md` for color, typography, and component patterns.
|
||||
- **Backend patterns:** Express route handlers in `src/index.ts`, business logic in `src/services/`. All new endpoints must use `authMiddleware`. SQL must use parameterized queries.
|
||||
|
||||
---
|
||||
|
||||
## Pull request workflow
|
||||
|
||||
1. Create a branch from `main` (e.g. `feat/my-feature`, `fix/my-bug`)
|
||||
2. Use [Conventional Commits](https://www.conventionalcommits.org/) for all commit messages:
|
||||
- `feat:` — new user-facing feature (bumps minor version)
|
||||
- `fix:` — bug fix (bumps patch version)
|
||||
- `docs:` — documentation changes (no version bump)
|
||||
- `chore:`, `ci:`, `refactor:`, `test:`, `perf:` — internal changes (no version bump)
|
||||
3. Update `CHANGELOG.md` under `## [Unreleased]` for user-facing changes
|
||||
4. Update or create documentation in `/docs` if behavior changes
|
||||
5. Open a PR targeting `main`
|
||||
6. Ensure CI passes before requesting review
|
||||
|
||||
Keep PRs focused — one feature or fix per PR.
|
||||
|
||||
---
|
||||
|
||||
## Project structure
|
||||
|
||||
```
|
||||
Sencho/
|
||||
├── backend/ # Express.js API + Docker orchestration
|
||||
│ ├── src/
|
||||
│ │ ├── index.ts # Route definitions (monolithic)
|
||||
│ │ ├── services/ # Business logic (17 services)
|
||||
│ │ └── __tests__/ # Vitest unit tests
|
||||
│ └── package.json
|
||||
├── frontend/ # React 19 + Vite SPA
|
||||
│ ├── src/
|
||||
│ │ ├── components/ # UI components
|
||||
│ │ ├── context/ # React context providers
|
||||
│ │ ├── lib/ # Utilities (apiFetch, etc.)
|
||||
│ │ └── App.tsx # Root router
|
||||
│ └── package.json
|
||||
├── docs/ # Mintlify documentation site
|
||||
├── e2e/ # Playwright E2E test specs
|
||||
├── Dockerfile # Multi-stage production build
|
||||
├── docker-compose.yml # Quick-start deployment
|
||||
└── package.json # Root scripts (test, test:e2e)
|
||||
```
|
||||
|
||||
For more detail on how the components relate, see the [Architecture Overview](/reference/architecture).
|
||||
Reference in New Issue
Block a user