ServerBee

Architecture

Technical overview of ServerBee's system design, components, and protocols.

This page describes the internal architecture of ServerBee for developers and operators who want to understand how the system works under the hood.

System Overview

+--------------------------------------------------+
|              ServerBee Dashboard                  |
|                                                   |
|  +---------------------------------------------+ |
|  | Frontend (React SPA, embedded via rust-embed)| |
|  | React 19, TanStack Router/Query             | |
|  | shadcn/ui, Tailwind CSS v4, Recharts        | |
|  +---------------------------------------------+ |
|  +---------------------------------------------+ |
|  | Server (Rust)                                | |
|  | Axum Router                                  | |
|  |  +-- REST API handlers                      | |
|  |  +-- WebSocket: Agent + Browser + Terminal   | |
|  |  +-- Static files (rust-embed)              | |
|  | Service Layer                                | |
|  |  +-- AgentManager (connections/state)        | |
|  |  +-- AlertService (rule evaluation)          | |
|  |  +-- RecordService (metrics/aggregation)     | |
|  |  +-- NotificationService (dispatch)          | |
|  | Entity Layer (sea-orm)                       | |
|  |  +-- SQLite                                  | |
|  +---------------------------------------------+ |
+--------------------------+-----------------------+
                           | WebSocket (JSON + Binary)
+--------------------------v-----------------------+
|              ServerBee Agent (Rust)               |
|  common crate (shared types/protocol)             |
|  +-- Collector (system metrics)                   |
|  +-- Reporter (WebSocket + reconnect)             |
|  +-- Pinger (ICMP/TCP/HTTP probes)                |
|  +-- TerminalManager (PTY sessions)               |
+---------------------------------------------------+

Component Roles

Server (crates/server)

The central hub that:

  • Serves the web dashboard (React SPA embedded via rust-embed)
  • Exposes REST API endpoints for CRUD operations
  • Manages WebSocket connections from agents and browsers
  • Stores all data in SQLite
  • Runs background tasks (record writing, aggregation, cleanup, alerting, offline detection)
  • Dispatches notifications

Agent (crates/agent)

A lightweight daemon that:

  • Collects system metrics using the sysinfo crate
  • Reports metrics to the server over WebSocket every N seconds
  • Runs ping probes as instructed by the server
  • Provides PTY terminal sessions for remote shell access
  • Executes remote commands dispatched by the server
  • Supports self-upgrade when instructed

Common (crates/common)

A shared library crate containing:

  • Protocol definitions -- AgentMessage, ServerMessage, BrowserMessage enums
  • Data types -- SystemInfo, SystemReport, GpuReport, PingResult, ServerStatus, etc.
  • Constants -- Default ports, timeouts, retention periods, alert parameters

Frontend (apps/web)

A React 19 single-page application:

  • Routing -- TanStack Router (file-based)
  • Data fetching -- TanStack Query for REST, native WebSocket for real-time updates
  • UI components -- shadcn/ui with the base-nova theme
  • Styling -- Tailwind CSS v4
  • Charts -- Recharts via shadcn Chart wrappers
  • Build -- Vite 7

The built frontend is embedded into the server binary at compile time, so there is nothing to deploy separately.

Communication Protocol

All communication uses WebSocket with JSON-encoded messages. Terminal data uses base64 encoding within the JSON frames.

Agent to Server (AgentMessage)

Message TypePurpose
SystemInfoStatic system information, sent once on connect
ReportPeriodic metric report (every N seconds)
PingResultResult of a ping probe
TaskResultOutput from a remote command execution
TerminalOutputPTY output data (base64-encoded)
TerminalStartedConfirmation that a PTY session was created
TerminalErrorError from a terminal session
PongProtocol-level heartbeat response
DockerInfoDocker system info and feature report
DockerContainersCurrent container list with status
DockerStatsContainer resource usage statistics
DockerLogContainer log entries (batched)
DockerEventContainer lifecycle event

Server to Agent (ServerMessage)

Message TypePurpose
WelcomeSent on connect with server_id, protocol_version, report_interval
AckAcknowledges a received message (by msg_id)
PingTasksSyncSync all assigned ping tasks to the agent
ExecExecute a shell command on the agent
TerminalOpenRequest to open a new PTY session
TerminalInputForward keyboard input to a PTY session
TerminalResizeResize a PTY session
TerminalCloseClose a PTY session
PingProtocol-level heartbeat
UpgradeInstruct the agent to self-upgrade
DockerLogsStartStart streaming logs for a container
DockerLogsStopStop streaming logs
DockerActionExecute container action (start/stop/restart/remove)

Server to Browser (BrowserMessage)

Message TypePurpose
FullSyncComplete state of all servers (sent on browser connect)
UpdateIncremental update with latest metrics for changed servers
ServerOnlineNotification that a server came online
ServerOfflineNotification that a server went offline
DockerUpdateDocker container and stats update
DockerEventDocker container lifecycle event
DockerAvailabilityChangedDocker daemon availability changed

Database Design

ServerBee uses SQLite with 25 tables across 5 categories:

Authentication (4 tables)

TablePurpose
usersUser accounts (id, username, password_hash, role, TOTP secret)
sessionsActive login sessions (token, IP, user agent, expiry)
api_keysAPI key credentials (hashed key, prefix, last used)
oauth_accountsLinked OAuth provider accounts

Server Management (4 tables)

TablePurpose
serversRegistered servers (system info, metadata, pricing, group assignment)
server_groupsLogical groups for organizing servers
server_tagsTag labels attached to servers
configsKey-value configuration store (auto-discovery key, etc.)

Monitoring Data (9 tables)

TablePurpose
recordsRaw metric records (one row per server per minute)
records_hourlyHourly aggregated metric averages
gpu_recordsPer-GPU device metrics (device index, name, memory, utilization, temp)
ping_recordsPing probe results (latency, success, error)
ping_tasksPing task definitions (probe type, target, interval, assigned servers)
traffic_hourlyHourly traffic byte counters (in/out) per server
traffic_dailyDaily traffic byte counters (in/out) per server
traffic_stateLast-known cumulative traffic counters for delta calculation
docker_eventsDocker container lifecycle events (start/stop/die/create)

Alerting & Operations (6 tables)

TablePurpose
alert_rulesAlert rule definitions (conditions, cover type, trigger mode)
alert_statesCurrent alert state per rule/server pair (triggered, resolved)
notificationsNotification channel configs (webhook, telegram, bark, email)
notification_groupsGroups of notification channels
tasksRemote command tasks (command, target servers, created by)
task_resultsCommand execution results (output, exit code)
audit_logsUser action audit trail (action, detail, IP)

All tables use UTC timestamps. IDs are UUIDs (string type) for most entities, and auto-incrementing integers for high-volume records.

Background Tasks

The server spawns six long-running background tasks:

TaskIntervalDescription
RecordWriter60sFlushes all cached agent reports from memory to the database
OfflineChecker10sScans for agents that have not sent a heartbeat in 30 seconds and marks them offline
Aggregator1 hourComputes hourly averages from raw records for long-term storage
Cleanup1 hourDeletes records, GPU data, ping records, and audit logs older than their retention periods
SessionCleanerPeriodicRemoves expired user login sessions
AlertEvaluator60sEvaluates all enabled alert rules against current data and dispatches notifications

Security Model

Authentication Layers

ServerBee supports three authentication mechanisms:

  1. Session-based (browser) -- User logs in with username/password, receives a session cookie. Sessions have a configurable TTL (default 24 hours).
  2. API Key (automation) -- Users can create named API keys for programmatic access. Keys are hashed with SHA-256 and stored with an 8-character prefix for identification.
  3. Agent Token (agents) -- Each registered server has a unique token hashed with argon2. Agents authenticate by providing the raw token as a query parameter on the WebSocket connection.

Role-Based Access

Two roles exist:

RoleCapabilities
adminFull access: manage users, servers, alerts, notifications, terminal, settings
userRead-only dashboard access (no terminal, no administrative actions)

OAuth

OAuth login is supported for GitHub, Google, and generic OIDC providers. The allow_registration flag controls whether new users are automatically created on first OAuth login.

Rate Limiting

Login and agent registration endpoints are rate-limited to prevent brute-force attacks (default: 5 login attempts, 3 registration attempts per window).

TOTP

Users can enable TOTP-based two-factor authentication for additional security.

Workspace Structure

ServerBee/
  crates/
    common/          # Shared types, protocol, constants
    server/          # Server binary (Axum, sea-orm, background tasks)
    agent/           # Agent binary (collector, reporter, terminal)
  apps/
    web/             # React frontend (Vite, TanStack, shadcn/ui)
    fumadocs/        # Documentation site
  docs/              # Design documents and plans
  Cargo.toml         # Workspace root

The project uses a Cargo workspace for the Rust crates. The frontend is a separate Bun/Node project under apps/web/.

On this page