---
title: Architecture Overview
description: System design, request flow, 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 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, including which node should handle each request
3. The backend evaluates which node is targeted:
   - **Local node:** The request passes through authentication and hits the local route handler, which communicates with Docker via the mounted socket
   - **Remote node:** The request is securely proxied to the target Sencho instance with appropriate authentication
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 — no external database required. The schema covers user identity, node configuration, automation rules, monitoring data, and security audit trails. Sensitive values (such as registry credentials and node tokens) are encrypted at rest.

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 handled automatically by the frontend. API users can target a specific node using a request header or query parameter (see [API Overview](/api-reference/overview))

---

## 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 are authenticated during the upgrade handshake using the same JWT credentials as HTTP requests.

---

## 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`.
