部署指南

生产环境下 ServerBee 服务端和 Agent 的部署策略。

本文介绍在生产环境部署 ServerBee 的最佳实践:Railway、Docker、systemd、反向代理配置、TLS 和备份策略。

Railway(一键部署)

Deploy on Railway

最快的部署方式。点击上方按钮,然后配置以下环境变量:

SERVERBEE_LOG__LEVEL="info"                    # 日志级别(trace/debug/info/warn/error)

SERVERBEE_RETENTION__RECORDS_DAYS="7"          # 原始指标保留天数
SERVERBEE_RETENTION__RECORDS_HOURLY_DAYS="90"  # 小时聚合保留天数
SERVERBEE_RETENTION__AUDIT_LOGS_DAYS="180"     # 审计日志保留天数
SERVERBEE_SCHEDULER__TIMEZONE="UTC"            # 时区,影响流量按天聚合(如 Asia/Shanghai)

SERVERBEE_OAUTH__BASE_URL=""                   # OAuth 回调公网地址(如 https://xxx.up.railway.app)
SERVERBEE_OAUTH__GITHUB__CLIENT_ID=""          # GitHub OAuth Client ID
SERVERBEE_OAUTH__GITHUB__CLIENT_SECRET=""      # GitHub OAuth Client Secret
SERVERBEE_OAUTH__ALLOW_REGISTRATION="false"    # 首次 OAuth 登录自动创建账号(true=开放注册,false=仅已绑定用户可登录)

部署后:

  1. 添加 Volume 挂载到 /data,以在多次部署间持久化数据
  2. 将 Agent 配置为使用 Railway 提供的 URL 进行连接
  3. 首次启动时,服务端会自动创建管理员账号并随机生成密码。打开 Railway 部署日志,查找醒目的凭据横幅即可获取该密码。首次登录时你必须修改此密码,并可选择一个新的用户名。

Railway 会自动分配端口并提供 HTTPS,无需配置 SERVERBEE_SERVER__LISTEN 或 TLS 证书。

选择 Railway 版本

源码模板会固定为仓库当前包版本,目前是 1.0.0-beta.4。ServerBee 尚无稳定 1.x 版本时,这可避免静默部署 :latest 所指向的旧镜像。

要锁定到指定版本(稳定版或预发版),在 Railway 服务的 Variables 里新增一条变量:

SERVERBEE_IMAGE_TAG=1.0.0-beta.4

保存后触发 Redeploy。修改版本前先查看 Release 页面。后续预发布版也会更新浮动 beta tag,latest 只由无后缀稳定版更新;需要可重复部署时仍应固定精确版本。

Dockerfile 通过 ARG SERVERBEE_IMAGE_TAG=1.0.0-beta.4 暴露这个开关。Railway 会自动把 Service Variables 同时作为构建参数和运行时环境变量注入;该变量不在 SERVERBEE_* 配置体系中,因此对运行时无副作用。

引导安装

在 Linux 主机上,最快的二进制 + systemd 部署方式是使用引导安装脚本:

# 安装服务端
curl -fsSL https://raw.githubusercontent.com/ZingerLittleBee/ServerBee/main/deploy/install.sh | sudo sh -s -- server

# 安装 Agent
curl -fsSL https://raw.githubusercontent.com/ZingerLittleBee/ServerBee/main/deploy/install.sh | sudo sh -s -- agent \
  --server-url http://your-server-ip:9527 \
  --enrollment-code YOUR_ONE_TIME_CODE

安装完成后,使用 serverbee CLI 管理你的部署(安装时会自动部署到 /usr/local/bin/serverbee):

sudo serverbee status
sudo serverbee upgrade -y
sudo serverbee upgrade --channel beta -y   # 显式保持预发布轨道
sudo serverbee restart
sudo serverbee config
sudo serverbee env
sudo serverbee uninstall agent -y

install server / install agent 是引导命令。如果 /usr/local/bin 中已经存在对应二进制,安装脚本会直接沿用现有文件而不会覆盖。向已部署主机下发新 release 二进制时,请改用 upgrade(或手动替换二进制)。

默认 auto 通道会在无后缀稳定版存在时选择最新稳定版,否则回退到最新预发布版。安装器会按组件保存该策略,并在升级时复用。传 --channel stable 或 --channel beta 可显式固定轨道,也可用 --version vX.Y.Z-beta.N 固定精确版本。CLI 会拒绝用较旧的 SemVer 覆盖当前安装。

Docker Compose(推荐)

Docker Compose 是在生产环境部署 ServerBee 最简单的方式。先创建配置文件(不能让不存在的 bind source 被 Docker 自动建成目录):

mkdir -p config
cat > config/server.toml <<'EOF'
[server]
data_dir = "/data"
EOF

然后在 config 同级创建 docker-compose.yml:

services:
  serverbee-server:
    image: ghcr.io/zingerlittlebee/serverbee-server:1.0.0-beta.4
    container_name: serverbee-server
    restart: unless-stopped
    ports:
      - "127.0.0.1:9527:9527"
    volumes:
      - serverbee-data:/data
      - ./config/server.toml:/etc/serverbee/server.toml:ro
    environment:
      - SERVERBEE_AUTH__SECURE_COOKIE=true
    healthcheck:
      test: ["CMD", "wget", "--spider", "-q", "http://127.0.0.1:9527/healthz"]
      interval: 30s
      timeout: 5s
      retries: 3
      start_period: 10s

volumes:
  serverbee-data:

将端口绑定到 127.0.0.1:9527 而非 0.0.0.0:9527,可确保服务端只能通过反向代理访问,而无法从公网直接访问。

启动服务:

docker compose up -d

查看日志:

docker compose logs -f serverbee-server

源码编译

开发者或有定制需求的用户可以从源码编译 ServerBee。源码编译需要 Rust 1.89+ 和 Bun 1.x(或 Node.js 22+)。

# 克隆仓库
git clone https://github.com/ZingerLittleBee/ServerBee.git
cd ServerBee

# 构建前端
cd apps/web
bun install
bun run build
cd ../..

# 构建服务端(通过 rust-embed 内嵌前端静态资源)
cargo build --release -p serverbee-server

# 构建 Agent
cargo build --release -p serverbee-agent

编译产物位于 target/release/ 目录下:

  • serverbee-server — 服务端,内嵌前端静态资源
  • serverbee-agent — 指标采集 Agent

启动服务端:

./target/release/serverbee-server

将编译好的二进制部署到目标主机后,可以参考下文的 systemd 服务配置进行进程管理。

systemd 服务

对于不使用 Docker 的部署,可以用 systemd 管理服务端和 Agent 进程。

如果你不需要手写 unit 文件,更推荐上面的引导安装方式。它会为你自动生成配置文件和 systemd unit,后续通过 serverbee CLI 统一完成升级、重启和配置修改。

注意:下面的 unit 示例采用自定义路径(/usr/local/bin、/var/lib/serverbee、/etc/serverbee)演示手动部署。引导脚本安装的实际布局不同——二进制在 /opt/serverbee/bin/、配置在 /opt/serverbee/etc/、数据在 /opt/serverbee/data/,且由 serverbee CLI 托管,无需手写 unit。

Server 服务

创建 /etc/systemd/system/serverbee-server.service:

[Unit]
Description=ServerBee Server
After=network-online.target
Wants=network-online.target

[Service]
Type=simple
ExecStart=/usr/local/bin/serverbee-server
Restart=always
RestartSec=5
User=serverbee
Group=serverbee
WorkingDirectory=/var/lib/serverbee

# 安全加固
NoNewPrivileges=true
ProtectSystem=strict
ProtectHome=true
ReadWritePaths=/var/lib/serverbee /var/log/serverbee
PrivateTmp=true

# 资源限制
MemoryMax=512M

[Install]
WantedBy=multi-user.target

创建服务用户和目录:

# 创建系统用户
sudo useradd -r -s /sbin/nologin -d /var/lib/serverbee serverbee

# 创建目录
sudo mkdir -p /var/lib/serverbee /var/log/serverbee /etc/serverbee
sudo chown serverbee:serverbee /var/lib/serverbee /var/log/serverbee

# 放置配置文件
sudo cp server.toml /etc/serverbee/server.toml

# 放置二进制
sudo cp serverbee-server /usr/local/bin/
sudo chmod +x /usr/local/bin/serverbee-server

systemd 部署使用的生产 server.toml:

[server]
listen = "127.0.0.1:9527"
data_dir = "/var/lib/serverbee"

[log]
level = "info"
file = "/var/log/serverbee/server.log"

启用并启动:

sudo systemctl daemon-reload
sudo systemctl enable serverbee-server
sudo systemctl start serverbee-server
sudo systemctl status serverbee-server

Agent 服务

完整的 Agent systemd 服务 unit 文件请参见 Agent 配置 指南。

反向代理

强烈建议在生产环境中将 ServerBee 部署在反向代理之后。反向代理可以提供 TLS 终止、HTTP/2 以及额外的安全响应头。

先确定一个对外访问地址,并让浏览器地址、Agent 的 server_url 和 Cookie 配置保持一致:

场景对外地址auth.secure_cookieDocker 环境变量Agent 地址
IP 直连,普通 HTTPhttp://203.0.113.10:9527falseSERVERBEE_AUTH__SECURE_COOKIE=falsehttp://203.0.113.10:9527
域名 + HTTPS 反向代理https://monitor.example.comtrueSERVERBEE_AUTH__SECURE_COOKIE=true 或不设置该变量https://monitor.example.com

使用域名访问时,需要先添加 DNS A 或 AAAA 记录指向服务器,再用 Nginx、Caddy 或 Traefik 终止 HTTPS,并把请求反向代理到 ServerBee 的 127.0.0.1:9527。

如果你是通过快速开始脚本安装的,脚本会为了 HTTP 直连写入 auth.secure_cookie = false。在把同一套安装切换到 HTTPS 前,请修改 /opt/serverbee/etc/server.toml:

[auth]
secure_cookie = true

然后重启服务端:

sudo systemctl restart serverbee-server

如果 ServerBee 已经通过安装脚本部署,也可以让 CLI 自动完成 Caddy HTTPS 配置:

sudo serverbee domain setup --domain monitor.example.com --email admin@example.com -y

该命令会校验域名是否解析到当前服务器,安装并配置 Caddy,把 ServerBee 改为只监听 127.0.0.1:9527,并把 auth.secure_cookie 设置为 true。如果 DNS 还没生效,命令会停止并打印你需要添加的 A/AAAA 记录。

Nginx

upstream serverbee {
    server 127.0.0.1:9527;
}

server {
    listen 80;
    server_name monitor.example.com;
    return 301 https://$host$request_uri;
}

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

    ssl_certificate     /etc/letsencrypt/live/monitor.example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/monitor.example.com/privkey.pem;
    ssl_protocols       TLSv1.2 TLSv1.3;
    ssl_ciphers         HIGH:!aNULL:!MD5;

    # 安全响应头
    add_header X-Frame-Options "SAMEORIGIN" always;
    add_header X-Content-Type-Options "nosniff" always;
    add_header Referrer-Policy "strict-origin-when-cross-origin" always;

    location / {
        proxy_pass http://serverbee;
        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 支持(Agent、浏览器实时更新和终端均需要)
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";

        # 为长连接 WebSocket 设置较长的超时
        proxy_read_timeout 86400s;
        proxy_send_timeout 86400s;

        # 关闭缓冲以支持实时数据
        proxy_buffering off;
    }
}

Caddy

Caddy 会自动使用 Let's Encrypt 处理 TLS:

monitor.example.com {
    reverse_proxy 127.0.0.1:9527 {
        # Caddy 默认支持 WebSocket
    }
}

这就是所需的全部 Caddy 配置。Caddy 默认处理 HTTPS 证书、HTTP/2、WebSocket 升级和安全响应头。

Traefik

Traefik 通过 Docker labels 集成,无需单独的配置文件。Traefik 会自动检测 WebSocket 连接,无需额外配置。

services:
  serverbee-server:
    image: ghcr.io/zingerlittlebee/serverbee-server:1.0.0-beta.4
    volumes:
      - serverbee-data:/data
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.serverbee.rule=Host(`monitor.example.com`)"
      - "traefik.http.routers.serverbee.entrypoints=websecure"
      - "traefik.http.routers.serverbee.tls.certresolver=letsencrypt"
      - "traefik.http.services.serverbee.loadbalancer.server.port=9527"
    restart: unless-stopped
    networks:
      - traefik

networks:
  traefik:
    external: true

volumes:
  serverbee-data:

TLS / HTTPS

生产环境部署请始终使用 HTTPS。推荐的方式如下:

Let's Encrypt + Certbot(Nginx)

sudo apt install certbot python3-certbot-nginx
sudo certbot --nginx -d monitor.example.com

Certbot 会自动配置 nginx 并设置证书续期。

Let's Encrypt + Caddy

Caddy 会自动申请和续期证书,无需额外设置。

手动证书

如果你有自己的证书,请把它们放在一个安全目录中,并在反向代理配置里引用。确保证书文件可被代理进程读取,并且你已经准备好续期机制。

Agent HTTPS 连接配置

当服务端部署在 HTTPS 之后时,需要相应地更新 Agent 的 server_url:

server_url = "https://monitor.example.com"

Agent 会自动根据提供的 URL 处理 WebSocket 连接。

ServerBee 自身不处理 TLS 终止。所有 HTTPS/WSS 加密都由前置的反向代理(Nginx/Caddy/Traefik)处理。这种架构简化了服务端的实现,也便于统一管理证书。

使用 HTTPS 时,请在服务端配置中保持 auth.secure_cookie = true。设为 false 可能仍然可以登录,但会去掉浏览器的 Secure Cookie 保护,不适合生产环境。

备份与恢复

备份哪些内容

SQLite 保存监控记录、用户、设置和上传的组件包。部分资产存放在独立文件中,仅下载数据库不能恢复完整安装:

项目位置数据库备份是否包含说明
数据库{data_dir}/serverbee.db是默认 database.path;包含数据库中的设置和组件包
品牌资产{data_dir}/brand/否上传的 Logo 和 favicon;数据库只保存访问 URL,不保存图片内容
下载的 GeoIP 国家数据库{data_dir}/dbip-country-lite.mmdb否已下载的 DB-IP Lite Country 数据库
下载的 ASN 数据库{data_dir}/dbip-asn-lite.mmdb否已下载的 DB-IP Lite ASN 数据库
自定义 MMDB 文件geoip.mmdb_path、asn.mmdb_path否配置路径位于 data_dir 之外时,需单独保存
服务端配置/opt/serverbee/etc/否安装器配置和版本通道策略;还需保存外部环境文件和密钥
Agent 配置与状态/opt/serverbee/etc/agent.toml、配置的 state_dir 和 security.data_dir否在每台 Agent 主机上单独备份,包括运行令牌;Server 备份不会复制远程文件

serverbee.db-wal 可能包含尚未写入主数据库的变更。运行中的服务端应使用 SQLite .backup 或备份 API,不要分别复制数据库和 sidecar 文件。停机后的完整目录快照会一并保留剩余的 serverbee.db-wal 和 serverbee.db-shm。

备份策略

下方示例使用安装器默认路径:/opt/serverbee/data/serverbee.db 和 /opt/serverbee/etc/。请按实际部署替换数据目录、数据库文件名、配置目录及外部 MMDB 路径。Docker 示例采用上文的 Compose 布局(/data、config/server.toml 和 docker-compose.yml)。

主机文件操作以 root 身份执行,需安装 sqlite3 CLI,并限制备份目录的访问权限。先创建一个带时间戳的目录,保存数据库及配套资产:

set -e
umask 077
SERVERBEE_BACKUP_DIR="/backups/serverbee-$(date -u +%Y%m%dT%H%M%SZ)"
mkdir -p "$SERVERBEE_BACKUP_DIR"

方式零:内置管理员备份 API,仅数据库

管理员专用 /api/settings/backup 端点使用 SQLite VACUUM INTO,仅导出数据库,不包含品牌图片、MMDB 文件、配置或 Agent 状态。把管理员 API key 放在环境变量中:

curl --fail --request POST \
  --header "X-API-Key: ${SERVERBEE_ADMIN_API_KEY}" \
  --output "$SERVERBEE_BACKUP_DIR/serverbee.db" \
  https://monitor.example.com/api/settings/backup
test "$(sqlite3 "$SERVERBEE_BACKUP_DIR/serverbee.db" 'PRAGMA integrity_check;')" = ok

若在另一台主机上下载数据库,请在 Server 主机上生成资产和配置归档,再复制到同一份备份目录中。

方式一:SQLite 备份命令,仅数据库

sqlite3 /opt/serverbee/data/serverbee.db ".backup '$SERVERBEE_BACKUP_DIR/serverbee.db'"
test "$(sqlite3 "$SERVERBEE_BACKUP_DIR/serverbee.db" 'PRAGMA integrity_check;')" = ok

以上两种数据库备份还需配套以下归档。assets.tar.gz 保存数据目录中除当前数据库及其 sidecar 之外的文件,包含已存在的 brand/ 和两种下载的 MMDB 文件;config.tar.gz 保存安装器配置目录:

tar czf "$SERVERBEE_BACKUP_DIR/assets.tar.gz" \
  --exclude='./serverbee.db*' -C /opt/serverbee/data .
tar czf "$SERVERBEE_BACKUP_DIR/config.tar.gz" -C /opt/serverbee etc

收集这一组文件时,请保持品牌资产、MMDB 下载和配置不变。分别在线复制不构成原子快照;这些文件正在变化时,请使用下方的停机快照。还需把外部 geoip.mmdb_path、asn.mmdb_path、环境文件及密钥加入备份,并记录原始路径。验证后将完整备份复制到 ServerBee 主机之外。

方式二:完整主机快照,需要停止服务端

set -e
sudo systemctl stop serverbee-server
tar czf "$SERVERBEE_BACKUP_DIR/data.tar.gz" -C /opt/serverbee/data .
tar czf "$SERVERBEE_BACKUP_DIR/config.tar.gz" -C /opt/serverbee etc
sudo systemctl start serverbee-server

数据归档包含数据库、剩余 WAL/SHM 文件、品牌资产和下载的 MMDB。外部文件仍需按上文单独保存。归档命令失败时,先解决问题,再重启并确认备份完整。

方式三:完整 Docker volume 与配置快照

set -e
umask 077
SERVERBEE_BACKUP_DIR="$PWD/backups/serverbee-$(date -u +%Y%m%dT%H%M%SZ)"
mkdir -p "$SERVERBEE_BACKUP_DIR"
docker compose stop serverbee-server

SERVERBEE_DATA_VOLUME="$(
  docker inspect serverbee-server \
    --format '{{range .Mounts}}{{if eq .Destination "/data"}}{{println .Name}}{{end}}{{end}}'
)"
test -n "$SERVERBEE_DATA_VOLUME"

docker run --rm \
  --mount "type=volume,src=${SERVERBEE_DATA_VOLUME},dst=/data,readonly" \
  --mount "type=bind,src=${SERVERBEE_BACKUP_DIR},dst=/backups" \
  alpine tar czf /backups/data.tar.gz -C /data .
tar czf "$SERVERBEE_BACKUP_DIR/config.tar.gz" config docker-compose.yml

docker compose start serverbee-server

这会保存实际 /data volume 中的全部文件,包括品牌及下载的 MMDB 资产,并另行归档挂载的配置。Compose .env 文件、外部密钥及 MMDB bind mount 也需保存。不要假设 volume 的实际名称一定是 serverbee-data:Compose 通常会添加项目名前缀,引用错误名称可能创建一个空 volume。

恢复

启动 Server 前,先恢复数据库及对应的资产和配置。下方示例适用于配齐 assets.tar.gz 和 config.tar.gz 的数据库备份,使用安装器布局,并要求事先通过 PRAGMA integrity_check:

set -e
umask 077
SERVERBEE_RESTORE_DIR="/backups/serverbee-20260314T020000Z"
test "$(sqlite3 "$SERVERBEE_RESTORE_DIR/serverbee.db" 'PRAGMA integrity_check;')" = ok
test -f "$SERVERBEE_RESTORE_DIR/assets.tar.gz"
test -f "$SERVERBEE_RESTORE_DIR/config.tar.gz"
sudo systemctl stop serverbee-server

# Preserve the current state before replacing it.
SERVERBEE_BEFORE_RESTORE="/backups/before-restore-$(date -u +%Y%m%dT%H%M%SZ)"
mkdir -p "$SERVERBEE_BEFORE_RESTORE"
mv /opt/serverbee/data /opt/serverbee/etc "$SERVERBEE_BEFORE_RESTORE/"

# Restore into an empty directory, without the previous database WAL/SHM.
mkdir -p /opt/serverbee/data
cp "$SERVERBEE_RESTORE_DIR/serverbee.db" /opt/serverbee/data/serverbee.db
tar xzf "$SERVERBEE_RESTORE_DIR/assets.tar.gz" -C /opt/serverbee/data
tar xzf "$SERVERBEE_RESTORE_DIR/config.tar.gz" -C /opt/serverbee

# Restore external MMDB/environment files and service ownership before starting.
# For a dedicated service user: chown -R serverbee:serverbee /opt/serverbee/data
sudo systemctl start serverbee-server

停机主机快照则将 data.tar.gz 解压到空的数据目录,替代复制 serverbee.db 和解压 assets.tar.gz 两步。两种方式都需恢复对应的 config.tar.gz 和外部文件。启动前检查恢复的配置,旧环境变量或密钥服务中的值可能覆盖恢复的 TOML。

管理员专用 /api/settings/restore 端点接受原始 SQLite 文件,会把原数据库保留为 .pre-restore,并要求重启。它仅恢复数据库,不修改独立资产和配置,不能代替完整安装恢复。需要恢复这些文件时,请使用上方停机流程或 Docker 恢复流程。

自动备份

下方 cron 任务仅定时备份数据库。先安装 sqlite3,并执行 sudo install -d -m 0700 /backups 创建目录:

# /etc/cron.d/serverbee-backup
0 2 * * * root umask 077; sqlite3 /opt/serverbee/data/serverbee.db ".backup '/backups/serverbee-$(date +\%Y\%m\%d).db'" && find /backups -name 'serverbee-*.db' -mtime +30 -delete

它会在每天凌晨 2:00 运行,删除超过 30 天的数据库备份。资产和配置也需安排配套归档,尤其在品牌、MMDB 或配置发生变更后;验证后将完整备份复制到主机之外。

健康检查

ServerBee 提供一个健康检查端点:

GET /healthz

用它来确认服务端是否正在运行且响应正常。可以在你的监控系统、Docker 健康检查或负载均衡器中配置它。

Docker 健康检查

上面的 Docker Compose 示例已包含健康检查。连续 3 次失败只会把容器标记为 unhealthy,Docker 不会仅因 unhealthy 自动重启;restart policy 只在进程退出时生效。请从外部监控健康状态,再有意识地排查或重启。

外部监控

如果你使用外部的可用性监控服务,请把它指向:

https://monitor.example.com/healthz

这样就形成了「监控监控系统」的配置,当 ServerBee 自身宕机时你也会收到告警。

资源需求

ServerBee 面向轻量级 VPS 实例设计:

组件最低配置推荐配置
服务端 CPU1 vCPU2 vCPU
服务端内存128 MB256 MB
服务端磁盘100 MB + 数据1 GB+(取决于保留策略)
Agent CPU可忽略< 单核的 1%
Agent 内存实测稳态 cgroup 约 27 MB30–40 MB 余量

数据库大小取决于服务器数量、启用的数据写入功能、采样间隔和保留设置。请使用存储与容量规划中的实测 30 天基线、功能乘数和 WAL 预留建议,避免混用不同保留窗口的粗略估算。

官方 Linux release 二进制和 Docker 镜像使用 musl,MALLOC_ARENA_MAX 对这些构建无效。请测量实际部署版本和负载,不要按历史 glibc 记录决定容量。详见资源开销。

安全检查清单

将 ServerBee 暴露到公网前,请逐项确认:

升级指南

ServerBee 在启动时会自动运行数据库迁移,升级后无需手动执行任何迁移步骤。升级前请先备份完整的数据目录、配置和外部资产。

Docker:

docker compose pull
docker compose up -d            # 重启并自动运行迁移
docker compose ps

二进制:

wget https://github.com/ZingerLittleBee/ServerBee/releases/download/v1.0.0-beta.4/serverbee-server-linux-amd64
sudo systemctl stop serverbee-server
sudo mv serverbee-server-linux-amd64 /usr/local/bin/serverbee-server
sudo chmod +x /usr/local/bin/serverbee-server
sudo systemctl start serverbee-server

如果你使用安装脚本部署,sudo serverbee upgrade -y 会自动完成二进制下载、替换和重启。

卸载与清除

sudo serverbee uninstall <server|agent> 会停止并删除受管理的服务/容器与可执行文件,但有意保留配置和数据,便于重装。只有完成并验证备份后才使用 --purge -y;它还会删除安装器管理的配置、Server 数据或 Docker volume/image,并在没有剩余组件时删除管理 CLI。

以下残留需要单独确认:

  • Agent 运行状态默认位于 /var/lib/serverbee/capability_grants.json 和 /var/lib/serverbee/security。自定义 state_dir 或 security.data_dir 可能指向别处;确认没有其他 Agent 使用后再删除。
  • 域名配置可能安装 Caddy,并在 /etc/caddy/Caddyfile 加入域名块。卸载器不会删除软件包或共享代理配置。先备份文件,只删除 ServerBee 域名块,执行 sudo caddy validate --config /etc/caddy/Caddyfile,再运行 sudo systemctl reload caddy。仅当没有其他站点使用 Caddy 时才卸载它。
  • 非 purge 的 Docker 卸载会保留 Compose 文件、配置与 named volume。删除前先通过 docker inspect serverbee-server 核对准确 volume。

清理后确认没有 serverbee-* 服务/容器仍在运行,并确认 9527(若同时删除代理,还包括 80/443)的监听者符合预期。

数据库迁移失败与恢复

ServerBee 在 Rust 服务端启动过程中执行数据库迁移。迁移发生在 HTTP 监听端口启动之前;如果迁移失败,进程会退出,Docker 的 restart: unless-stopped 或 systemd 的重启策略可能使服务进入重启循环。

当前版本不会在迁移前自动创建数据库快照,也没有自动回滚迁移。Docker volume 只能持久化文件,不是可回退的版本。所有迁移都是向前执行,迁移的 down() 不会恢复旧 schema。

可能失败的场景

类别典型原因推荐处理
存储不可写/data 权限错误、只读挂载、磁盘或 inode 耗尽停止重启循环,修复存储问题,然后重新执行迁移
数据库锁另一个 ServerBee 实例、备份程序或 SQLite 客户端长期持有锁确认只有一个服务端写入数据库,停止冲突进程后重试
数据库损坏SQLite 主文件、WAL 或 SHM 损坏,主机异常断电保留故障现场,执行完整性检查,优先恢复已验证备份
schema 漂移手工修改过表、索引或迁移历史,实际结构与迁移记录不一致不要伪造迁移记录;恢复兼容备份或发布向前修复迁移
旧数据违反新约束重复值、空值、孤立外键或无法解析的历史数据在数据库副本中定位并修复数据,再重新执行迁移
迁移实现缺陷SQL、数据回填或目标 schema 本身有错误保留原数据库,部署包含修正版迁移的新镜像
执行中断迁移时容器被强制终止、主机重启或断电先制作故障快照;确认 schema 和迁移记录一致后再重试
多实例竞争多个容器同时对同一个 SQLite 文件启动迁移将服务缩容到一个实例;SQLite 部署不应由多个 Server 实例共享写入
版本回退不兼容新版迁移已成功,但随后只把镜像切回旧版同时恢复升级前数据库备份,或使用兼容新 schema 的应用版本

第一步:停止重启循环

Docker Compose:

docker compose stop serverbee-server

如果容器仍然被外部工具反复拉起,可以临时关闭容器级重启策略:

docker update --restart=no serverbee-server
docker stop serverbee-server

systemd:

sudo systemctl stop serverbee-server
sudo systemctl reset-failed serverbee-server

停止服务不会删除 Docker volume 或数据库文件。不要使用 docker compose down -v,其中的 -v 会删除 Compose 管理的 volume。

第二步:读取迁移错误

Docker:

docker logs --tail 200 serverbee-server

systemd:

sudo journalctl -u serverbee-server -b -n 200 --no-pager

迁移成功时日志中会出现 Database migrations complete。如果没有这条日志,请从第一条数据库或 migration 错误开始排查,不要只看后续重启信息。

第三步:保存故障现场

即使数据库可能已经处于部分迁移或损坏状态,也要先保存完整副本。它既是人工修复的输入,也是避免后续尝试覆盖证据的保险。

Docker:

SERVERBEE_DATA_VOLUME="$(
  docker inspect serverbee-server \
    --format '{{range .Mounts}}{{if eq .Destination "/data"}}{{println .Name}}{{end}}{{end}}'
)"
test -n "$SERVERBEE_DATA_VOLUME"

mkdir -p backups
docker run --rm \
  --mount "type=volume,src=${SERVERBEE_DATA_VOLUME},dst=/data,readonly" \
  --mount "type=bind,src=$(pwd)/backups,dst=/backups" \
  alpine \
  tar czf /backups/serverbee-failed-migration-$(date -u +%Y%m%dT%H%M%SZ).tar.gz -C /data .

systemd 或二进制部署,在服务停止后复制整个数据目录,而不是只复制主数据库文件:

sudo mkdir -p /backups
sudo cp -a /opt/serverbee/data \
  "/backups/serverbee-failed-migration-$(date -u +%Y%m%dT%H%M%SZ)"

故障数据快照还需配套保存配置、外部 MMDB 文件、环境文件和密钥。这些文件可能解释故障原因,也是完整恢复所需的内容。

第四步:检查数据库状态

在故障快照的副本上运行检查,不要直接修改唯一的生产 volume:

mkdir -p recovery-data
SERVERBEE_FAILED_BACKUP="$(ls -1t backups/serverbee-failed-migration-*.tar.gz | head -n 1)"
test -f "$SERVERBEE_FAILED_BACKUP"
tar xzf "$SERVERBEE_FAILED_BACKUP" -C recovery-data

sqlite3 recovery-data/serverbee.db "PRAGMA integrity_check;"
sqlite3 recovery-data/serverbee.db "PRAGMA foreign_key_check;"
sqlite3 recovery-data/serverbee.db \
  "SELECT * FROM seaql_migrations ORDER BY applied_at;"
  • PRAGMA integrity_check 应返回 ok。
  • PRAGMA foreign_key_check 正常情况下不返回任何记录。
  • seaql_migrations 展示已经记录为成功的迁移;全新数据库在迁移表创建前失败时,这张表可能不存在。

不要删除 seaql_migrations 中的记录,也不要手工把失败迁移标记为成功。迁移记录与真实 schema 不一致时,后续版本可能在更难恢复的位置失败。

第五步:选择恢复方式

环境问题

如果问题只是磁盘空间、权限、只读挂载或临时数据库锁,修复根因后重新启动。SeaORM 会再次执行尚未记录为成功的迁移:

docker update --restart=unless-stopped serverbee-server
docker compose up -d serverbee-server
docker logs -f serverbee-server

旧数据或 schema 不兼容

在数据库副本上识别冲突数据。优先发布能够处理旧数据的向前修复 migration;如果必须人工修改数据,先在副本上验证完整迁移和应用启动,再对生产数据库执行同一组已审查操作。

迁移代码缺陷

不要反复重启同一个失败镜像。保留故障现场,部署包含修正版 migration 的新镜像。仅切回旧镜像不等于数据库回滚;只有在确认失败迁移没有改变 schema 时才可能安全,否则应恢复升级前备份。

数据库损坏

优先恢复最近一次通过完整性检查的备份。SQLite .recover 只应作为没有可用备份时的数据抢救手段,恢复结果可能不完整,需要在隔离副本上验证。

从 Docker 备份恢复到新 volume

恢复时建议创建新 volume,不要覆盖故障 volume。这样可以随时切回故障现场继续分析:

SERVERBEE_RECOVERY_VOLUME="serverbee-data-recovery-$(date -u +%Y%m%dT%H%M%SZ)"
docker volume create "$SERVERBEE_RECOVERY_VOLUME"

docker run --rm \
  --mount "type=volume,src=${SERVERBEE_RECOVERY_VOLUME},dst=/data" \
  --mount "type=bind,src=$(pwd)/backups/serverbee-20260314T020000Z,dst=/backups,readonly" \
  alpine \
  tar xzf /backups/data.tar.gz -C /data

echo "$SERVERBEE_RECOVERY_VOLUME"

# Inspect the matching Compose/configuration archive before restoring it.
mkdir -p recovered-config
tar xzf backups/serverbee-20260314T020000Z/config.tar.gz -C recovered-config

检查 recovered-config/config/server.toml 和 recovered-config/docker-compose.yml,恢复到部署项目,并重新配置对应的外部 MMDB 挂载、环境文件和密钥。数据归档会恢复 brand/ 及下载的 MMDB 文件,无法恢复 /data 之外的文件。

然后让 Compose 中现有的 serverbee-data 逻辑名称指向刚创建的 volume:

volumes:
  serverbee-data:
    external: true
    name: serverbee-data-recovery-20260722T103000Z

确认 Compose 文件中的 name 与上一条命令输出完全一致,再启动服务。恢复较旧的数据库时,目标镜像可能再次执行迁移,因此应先确定要运行的是原版本还是包含修复的新版本。

恢复后验证

docker compose up -d serverbee-server
docker compose ps
docker logs --tail 200 serverbee-server
curl --fail http://127.0.0.1:9527/healthz

只有同时满足以下条件,才能认为恢复完成:

  • 日志包含 Database migrations complete。
  • 容器保持运行且健康检查通过。
  • PRAGMA integrity_check 返回 ok。
  • 能登录并读取已有 Server、告警和历史记录。
  • 原先配置的 Logo、favicon 和 GeoIP/ASN 数据库均可用。
  • 没有持续出现数据库锁、外键或缺失表/列错误。

预防措施

  • 每次升级前创建并验证完整的数据与配置备份;当前升级命令不会自动备份。
  • 将备份复制到 Docker 主机之外,避免主机磁盘故障同时损坏生产 volume 和本地备份。
  • SQLite 部署保持单个 Server 实例,不要让多个容器共享写入同一个数据库文件。
  • 升级前检查可用磁盘空间,并使用明确的镜像版本 tag,避免无法确认迁移来自哪个版本。
  • 保留升级前镜像及配套的数据库、资产和配置备份。数据库回退依赖备份,不能只依赖旧镜像。
  • 升级后等待迁移成功日志和健康检查,不要仅以 docker compose up -d 返回成功作为完成依据。