ServerBee

Server Setup

Install, configure, and run the ServerBee server.

The ServerBee server is the central component that hosts the web dashboard, manages agent connections, stores monitoring data, and evaluates alert rules. It is a single Rust binary with the React frontend embedded via rust-embed.

Installation

The easiest path is the one-line install script. It detects the architecture, downloads the binary, generates the config, registers and starts the systemd service, and symlinks the serverbee management CLI. The server supports two quick installs:

# Option A: install with an IP (plain HTTP), reachable at http://<server-ip>:9527
curl -fsSL https://raw.githubusercontent.com/ZingerLittleBee/ServerBee/main/deploy/install.sh | sudo bash -s -- server -y

# Option B: install with a domain (automatic Caddy + HTTPS), reachable at https://your-domain
curl -fsSL https://raw.githubusercontent.com/ZingerLittleBee/ServerBee/main/deploy/install.sh | sudo bash -s -- server \
  --domain monitor.example.com --email admin@example.com -y

Script layout: binary in /opt/serverbee/bin/, config in /opt/serverbee/etc/server.toml, data in /opt/serverbee/data/, and the management CLI symlinked to /usr/local/bin/serverbee. See Quick Install for the full walkthrough.

Pre-built Binary (manual)

Download the latest release for your platform from the releases page, then run it:

chmod +x serverbee-server
./serverbee-server

Docker

docker run -d \
  --name serverbee \
  -p 9527:9527 \
  -v serverbee-data:/data \
  ghcr.io/zingerlittlebee/serverbee-server:latest

Build from Source

# Build the frontend first
cd apps/web && bun install && bun run build && cd ../..

# Build the server binary
cargo build --release -p serverbee-server

Configuration File

The server reads configuration from TOML files in the following order, with later sources overriding earlier ones:

  1. /etc/serverbee/server.toml (system-wide)
  2. server.toml (working directory)
  3. Environment variables with SERVERBEE_ prefix

When deployed via the install script, the config lives at /opt/serverbee/etc/server.toml and data at /opt/serverbee/data/ (the script writes these paths explicitly, overriding the built-in defaults below). /etc/serverbee and /var/lib/serverbee are the legacy layout, only seen on older installs; the script migrates them automatically.

Here is a server.toml showing the most common options and their defaults. See the Configuration Reference for all available options.

[server]
listen = "0.0.0.0:9527"       # Address and port to listen on
data_dir = "./data"            # Directory for database and other data files
trusted_proxies = []           # Defaults to private/loopback CIDRs; set to [] to disable

[database]
path = "serverbee.db"          # Database filename (relative to data_dir)
max_connections = 10           # Maximum SQLite connection pool size

[auth]
session_ttl = 86400            # Session lifetime in seconds (default: 24 hours)
max_servers = 0                # Soft limit for newly enrolled servers
secure_cookie = true           # Set Secure flag on session cookies (disable for HTTP-only dev)

[retention]
records_days = 7               # Raw metric records retention (days)
records_hourly_days = 90       # Hourly aggregated records retention (days)
gpu_records_days = 7           # GPU metric records retention (days)
ping_records_days = 7          # Ping probe records retention (days)
audit_logs_days = 180          # Audit log retention (days)
network_probe_days = 7         # Network probe records retention (days)
network_probe_hourly_days = 90 # Hourly network probe aggregates retention (days)
traffic_hourly_days = 7        # Traffic hourly records retention (days)
traffic_daily_days = 400       # Traffic daily records retention (days)
task_results_days = 7          # Task results retention (days)
docker_events_days = 7         # Docker event records retention (days)
service_monitor_days = 30      # Service monitor records retention (days)

[rate_limit]
login_max = 5                  # Max login attempts per window
register_max = 3               # Max agent registration attempts per window

[scheduler]
timezone = "UTC"               # Timezone for daily traffic aggregation (e.g. Asia/Shanghai)

[log]
level = "info"                 # Log level: trace, debug, info, warn, error
file = ""                      # Log file path (empty = stdout only)

[upgrade]
release_base_url = "https://github.com/ZingerLittleBee/ServerBee/releases"  # Base URL for agent upgrades

[geoip]
mmdb_path = ""                 # Path to MaxMind GeoLite2-City.mmdb (non-empty enables GeoIP)

[oauth]
base_url = ""                  # Public URL of your ServerBee instance
allow_registration = false     # Allow new user creation on first OAuth login

[oauth.github]
client_id = ""
client_secret = ""

[oauth.google]
client_id = ""
client_secret = ""

[oauth.oidc]
issuer_url = ""
client_id = ""
client_secret = ""
scopes = ["openid", "email", "profile"]

Environment Variables

Every configuration option can be set via environment variables using the SERVERBEE_ prefix and __ (double underscore) as a nested key separator. Environment variables take precedence over TOML file values.

Examples:

# server.listen
export SERVERBEE_SERVER__LISTEN="0.0.0.0:9527"

# retention.records_days
export SERVERBEE_RETENTION__RECORDS_DAYS=14

# oauth.github.client_id
export SERVERBEE_OAUTH__GITHUB__CLIENT_ID="your-github-client-id"

# geoip.mmdb_path (non-empty path enables GeoIP)
export SERVERBEE_GEOIP__MMDB_PATH="/path/to/GeoLite2-City.mmdb"

Database

ServerBee uses SQLite for all persistent storage. The database file is created automatically in the configured data_dir when the server starts for the first time.

Key SQLite pragmas are set automatically:

PragmaValuePurpose
journal_modeWALBetter concurrent read performance
synchronousNORMALGood balance of safety and speed
busy_timeout5000msWait up to 5 seconds for locked database
foreign_keysONEnforce referential integrity

Database migrations run automatically on startup. No manual schema management is required.

Initial Admin Account

On first startup, if no users exist in the database, the server automatically creates an admin account. There is no username/password environment variable: the password is always randomly generated and printed once to the server/container logs as a highlighted credentials banner.

========================================
  ServerBee initial admin credentials
  Username: admin
  Password: aB3xK9mP2qR5
========================================

Capture this password from the logs. On first login you are required to change it, and you may optionally choose a different username at that time.

The generated password is shown only once in the logs. Record it before the logs rotate, and complete the forced password change on first login before exposing the server to the internet.

Enrollment Codes

Agents enroll with a one-time enrollment code instead of a permanent shared secret. An admin mints a code from Settings in the web UI (or via POST /api/agent/enrollments, admin-only, which returns { id, code, expires_at }). Enrollment codes have the following properties:

  1. Single-use -- the code is consumed on the agent's first successful registration and cannot be reused afterwards
  2. Short-lived -- expires after a default TTL of 600 seconds (10 minutes)
  3. After registration the agent uses its persisted per-server token; the code is no longer needed

If a code is lost, expired, or already used, the server responds with HTTP 401 and the agent logs Registration failed: HTTP 401 ... enrollment code ... expired or already used. To onboard another agent (or re-enroll one that lost its token), mint a fresh code in Settings. Use GET /api/agent/enrollments to list issued codes (returns only an 8-character prefix and metadata, never the plaintext code) and DELETE /api/agent/enrollments/{id} to delete an unused code.

To reduce duplicate placeholder servers, agents reuse the existing server row when they re-register with the same machine fingerprint. You can also set auth.max_servers to soft-cap newly enrolled servers, and use Clean up unconnected on the Servers page to remove offline placeholders that never finished initialization. A connected agent's run token can be rotated or revoked via POST /api/agent/{id}/rotate-token, which forces that agent to reconnect. After rotation the affected agent is disconnected and must be reconfigured with the new token, or re-enrolled with a fresh one-time enrollment code (the original code is single-use and was already consumed).

Recovering a Reinstalled Agent

If an existing server was reinstalled and then re-registered as a new temporary online node, you can recover it from the original offline server detail page:

  1. Open the original offline server.
  2. Click Recover Agent.
  3. Choose the recommended online replacement candidate.
  4. Start the recovery job.

The original server record is kept. The replacement agent is asked to rebind onto the original server identity, and the recovery flow continues from there.

Recovery is designed for reinstalling the same logical machine. It is not intended for arbitrary record merges or hardware migrations to a different host.

GeoIP Setup

To enable geographic location detection for your agents:

  1. Download the free MaxMind GeoLite2-City MMDB database (requires a free MaxMind account)
  2. Place the GeoLite2-City.mmdb file in an accessible location
  3. Enable GeoIP in your configuration:
[geoip]
mmdb_path = "/path/to/GeoLite2-City.mmdb"

The server will resolve each agent's IP address to a region and country code when it connects.

OAuth Setup

ServerBee supports third-party authentication through GitHub, Google, and any OpenID Connect provider.

Prerequisites

Set oauth.base_url to the public URL of your ServerBee instance. This is used to construct callback URLs:

[oauth]
base_url = "https://serverbee.example.com"
allow_registration = true  # Set to true to create accounts on first OAuth login

GitHub

  1. Go to GitHub Developer Settings and create a new OAuth App
  2. Set the callback URL to https://serverbee.example.com/api/auth/oauth/github/callback
  3. Add credentials to the config:
[oauth.github]
client_id = "your-client-id"
client_secret = "your-client-secret"

Google

  1. Create OAuth credentials in the Google Cloud Console
  2. Set the callback URL to https://serverbee.example.com/api/auth/oauth/google/callback
  3. Add credentials to the config:
[oauth.google]
client_id = "your-client-id"
client_secret = "your-client-secret"

Generic OIDC

For any OpenID Connect provider (e.g., Keycloak, Authentik, Authelia):

[oauth.oidc]
issuer_url = "https://auth.example.com/realms/main"
client_id = "serverbee"
client_secret = "your-client-secret"
scopes = ["openid", "email", "profile"]

Reverse Proxy

If you don't want to configure a reverse proxy by hand, the install script can do it for you: add --domain monitor.example.com --email admin@example.com at install time, or run sudo serverbee domain setup --domain monitor.example.com --email admin@example.com on an already-installed server. The script verifies DNS, installs Caddy, writes the Caddyfile, issues an HTTPS certificate, and sets auth.secure_cookie to true. The manual configuration below is only needed if you want to manage the reverse proxy yourself.

When running behind a reverse proxy, you must forward WebSocket connections correctly. Here is an nginx example:

server {
    listen 443 ssl http2;
    server_name serverbee.example.com;

    ssl_certificate     /etc/ssl/certs/serverbee.pem;
    ssl_certificate_key /etc/ssl/private/serverbee.key;

    location / {
        proxy_pass http://127.0.0.1:9527;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;

        # WebSocket support
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_read_timeout 86400s;
        proxy_send_timeout 86400s;
    }
}

The long proxy_read_timeout and proxy_send_timeout values are important for WebSocket connections. Without them, nginx may close idle connections prematurely, causing agents and terminal sessions to disconnect.

For more reverse proxy configurations including Traefik, see the Deployment Guide.

Background Tasks

The server runs several background tasks automatically:

TaskIntervalPurpose
RecordWriter60sWrites cached agent reports to the database
OfflineChecker10sDetects agents that stopped reporting (30s threshold)
AggregatorHourlyAggregates raw records into hourly summaries
CleanupHourlyRemoves expired records based on retention settings
SessionCleanerPeriodicRemoves expired user sessions
AlertEvaluator60sEvaluates all enabled alert rules

All tasks start automatically and require no manual configuration.

On this page