WBO 2.18.31 Docker Compose 部署指南

WBO 2.18.31 Docker Compose 部署指南:官方镜像实测部署全流程,覆盖目录规划、Compose 编排、nginx 反代 WebSocket 链路、SVG 持久化验证、备份升级与排障实录。

WBOWBODocker自托管白板2026/10/30

WBO 2.18.31 Docker Compose 部署指南

‍‍​​‌​> 本文是 WBO 专栏的部署篇。以下流程于 2026-10-30 在一台真实 Linux 服务器上实测走通:从零建目录、起服务、验证首页与板页、走通 nginx 反代 WebSocket 链路、验证 SVG 持久化到备份升级全链路。文中所有命令回显均为实测原文,环境为 Docker 29.9.2 + Docker Compose v5.6.1。组件画像见《WBO 2.18.31 介绍与选型指南》,参数逐项调优见《WBO 2.18.31 配置参数详解》,WebSocket 与 HTTP 接口实测见《WBO 2.18.31 常用操作与 API 详解》。

一、部署前决策

镜像与版本锁定:官方镜像为 Docker Hub 的 lovasoa/wbo。实测使用 lovasoa/wbo:latest,启动后页面标识为 data-wbo-version="2.18.31"、容器内 package.json 版本号为 2.18.31,即 latest 当前口径就是 2.18.31。生产建议锁定版本标签而不是跟随 latest,升级时显式改标签再拉取,保证可回退。

容器内监听口:镜像默认环境 PORT=80(容器内口),NODE_ENV=production,数据目录 WBO_HISTORY_DIR=/opt/app/server-data。宿主侧端口本文统一映射 8149:80(可按需调整,只需同步改反代与防火墙)。

是否需要 nginx:WBO 自带 HTTP + WebSocket 服务,纯内网可直接映射端口使用;公网或需要子路径、TLS 时建议前置 nginx。本文按生产常用形态给出「wbo + nginx」双服务编排,nginx 同时演示 /wbo/ 子路径反代与 WebSocket 升级头配置(这是 WBO 类组件反代最容易踩的坑)。

目录与端口规划(实测布局):

/opt/wbo/
├── docker-compose.yml
├── data/                  # 板持久化目录,映射到容器 /opt/app/server-data
└── nginx/
    └── default.conf       # 反代配置
端口用途
宿主 8149WBO 直连口(容器 80)
nginx 80反代口,/wbo/ 子路径转发到 wbo 容器

二、前置条件

  1. 已安装 Docker 与 Compose 插件(实测版本:Docker 29.9.2、Compose v5.6.1):
docker --version && docker compose version
Docker version 29.9.2, build a82e528
Docker Compose version v5.6.1
  1. 规划目录并就位:
mkdir -p /opt/wbo/data /opt/wbo/nginx
cd /opt/wbo

三、部署步骤

3.1 编写 docker-compose.yml

/opt/wbo/docker-compose.yml(与实测一致):

services:
  wbo:
    image: lovasoa/wbo:latest
    container_name: wbo-2.18.31-web
    restart: unless-stopped
    ports:
      - "8149:80"
    environment:
      - NODE_ENV=production
      - PORT=80
      - LOG_LEVEL=info
      - WBO_HISTORY_DIR=/opt/app/server-data
    volumes:
      - ./data:/opt/app/server-data
    networks:
      - wbo-net

  nginx:
    image: nginx:alpine
    container_name: wbo-nginx-test
    restart: unless-stopped
    depends_on:
      - wbo
    volumes:
      - ./nginx/default.conf:/etc/nginx/conf.d/default.conf:ro
    networks:
      - wbo-net

networks:
  wbo-net:
    driver: bridge

编排要点:data 目录用 bind mount 落宿主盘,备份与迁移就是复制目录;nginx 与 wbo 同一自定义网络,nginx 配置里可直接用服务名 wbo 作上游主机名(Docker 内置 DNS 解析)。

3.2 编写 nginx 反代配置

/opt/wbo/nginx/default.conf(实测原文):

log_format upstream '$remote_addr -> $upstream_addr $upstream_status "$request" $status';
server {
  listen 80;
  access_log /var/log/nginx/upstream.log upstream;
  location /wbo/ {
    proxy_pass http://wbo:80/;
    proxy_set_header X-Forwarded-For $remote_addr;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
  }
}

四个关键点缺一不可:

  • proxy_pass http://wbo:80/(末尾带 /):把 /wbo/ 前缀剥掉后转发,WBO 侧无需任何改动;
  • proxy_http_version 1.1 + Upgrade/Connection "upgrade":WebSocket 握手必需,漏掉 upgrade 头是白板「页面能开但画不上线」的最常见原因;
  • X-Forwarded-For:WBO 的按 IP 限流与封禁依赖真实客户端 IP,配合服务端 WBO_IP_SOURCE/WBO_TRUST_PROXY_HOPS 使用(见 C1);
  • 独立 log_format:$upstream_addr/$upstream_status 直接暴露上游健康度,排障效率高。

3.3 启动与验证

cd /opt/wbo && docker compose up -d
[+] Running 3/3
 ✔ Network wbo_wbo-net    Created
 ✔ Container wbo-2.18.31-web  Started
 ✔ Container wbo-nginx-test   Started

逐项验证(回显为实测原文):

# 1) WBO 直连口首页
curl -s -o /dev/null -w '%{http_code}\n' http://127.0.0.1:8149/
200
# 2) 版本口径确认
curl -s http://127.0.0.1:8149/ | grep -o 'data-wbo-version="[^"]*"'
data-wbo-version="2.18.31"
# 3) 板页按需创建(访问即建板)
curl -s -o /dev/null -w '%{http_code}\n' http://127.0.0.1:8149/boards/evidence-test
200
# 4) nginx 子路径链路:容器内自测 /wbo/ 前缀
docker exec wbo-nginx-test curl -s -o /dev/null -w '%{http_code}\n' http://localhost/wbo/boards/evidence-test
200
# 5) 反代访问日志:确认上游命中 wbo 容器
docker exec wbo-nginx-test tail -2 /var/log/nginx/upstream.log
127.0.0.1 -> 10.89.79.3:8080 200 "GET /wbo/boards/probe-index HTTP/1.1" 200
127.0.0.1 -> 10.89.79.3:8080 200 "GET /wbo/boards/evidence-test HTTP/1.1" 200

WebSocket 实测(两端同步画一笔 + 持久化)的完整脚本与逐条回显见 D1,此处先确认链路要素:Upgrade/Connection 头已配、上游 200、X-Forwarded-For 已透传。

四、数据持久化说明

WBO 的全部状态就是 data/ 目录里的一批 SVG 文件:每块板一个 <板名>.svg,格式为 whitebophir-svg-v2,文件头 data-wbo-seq 记录已持久化的操作序号。实测画一笔(pencil 三点)后约 2 秒(WBO_SAVE_INTERVAL 默认 2000ms)落盘:

ls -la /opt/wbo/data/
-rw-r--r-- 1 yahui yahui  705 Oct 30 02:18 board-synctest.svg
-rw-r--r-- 1 yahui yahui  382 Oct 30 02:19 board-ratetest.svg
-rw-r--r-- 1 yahui yahui  333 Oct 30 08:19 board-evidence-ws3.svg
cat /opt/wbo/data/board-evidence-ws3.svg
<svg id="canvas" xmlns="http://www.w3.org/2000/svg" version="1.1" width="5000" height="5000" data-wbo-format="whitebophir-svg-v2" data-wbo-seq="4" data-wbo-readonly="false"><defs id="defs"></defs><g id="drawingArea"><path id="pen-f1" d="M 120 130 l 160 130 l 140 -80" stroke="#0044cc" stroke-width="12" fill="none" stroke-linecap="round" stroke-linejoin="round"></path></g><g id="cursors"></g></svg>

注意两点:板名会出现在文件名里,特殊字符板名部署时留意转义;持久化是「定时 + 防抖」(WBO_SAVE_INTERVAL/WBO_MAX_SAVE_DELAY),强杀容器前留意最后一次写入窗口。备份策略:直接 cp 或 rsync 该目录即可,恢复时停服覆盖后重启。

五、环境变量表

部署时常用的最小集合(完整参数与默认值见 C1):

变量实测取值说明
PORT80容器内 HTTP 监听口(服务端默认 8080,镜像默认 80)
NODE_ENVproduction生产模式(非 production 视为开发模式)
LOG_LEVELinfo日志级别,可选 debug/info/warn/error
WBO_HISTORY_DIR/opt/app/server-data板持久化目录,务必映射到宿主卷
WBO_SAVE_INTERVAL2000落盘间隔毫秒(默认值)
WBO_MAX_EMIT_COUNT*:250/5s总 emit 限流档(默认值)
WBO_BOARD_MODERATORS未设板级版主密钥表,格式 板名:用户密钥

六、配置文件挂载

本文编排只挂载两处,均为最小必需:

宿主路径容器路径读写用途
./data/opt/app/server-datarw板 SVG 持久化
./nginx/default.conf/etc/nginx/conf.d/default.confro反代配置

WBO 本体无需配置文件,全部行为由环境变量驱动;如需注入统计脚本等自定义 <head> 内容,可用 WBO_HTML_HEAD_SNIPPET_PATH 指向容器内文件后再多挂一个只读卷(见 C1)。

七、等价 docker run

不使用 Compose 时的等价命令(单服务):

docker network create wbo-net
docker run -d --name wbo-2.18.31-web \
  --network wbo-net \
  -p 8149:80 \
  -e NODE_ENV=production -e PORT=80 -e LOG_LEVEL=info \
  -e WBO_HISTORY_DIR=/opt/app/server-data \
  -v /opt/wbo/data:/opt/app/server-data \
  --restart unless-stopped \
  lovasoa/wbo:latest

nginx 服务同理:

docker run -d --name wbo-nginx-test \
  --network wbo-net \
  -v /opt/wbo/nginx/default.conf:/etc/nginx/conf.d/default.conf:ro \
  --restart unless-stopped \
  nginx:alpine

八、常用运维命令

# 状态与资源
docker compose ps
docker stats --no-stream wbo-2.18.31-web

# 日志(服务端为结构化日志,LOG_LEVEL=info 足够日常排障)
docker compose logs -f wbo

# 备份:板目录整体复制
tar czf /backup/wbo-data-$(date +%F).tgz -C /opt/wbo data

# 升级:改 compose 中镜像标签后
docker compose pull wbo && docker compose up -d wbo

# 回滚:改回旧标签,data 目录不动
docker compose up -d wbo

升级安全性:数据格式是自描述的 SVG(data-wbo-format="whitebophir-svg-v2"),跨小版本升级风险低;升级前照例 tar 一份 data 目录即可。

九、常见问题

1. 页面能打开但别人画的东西看不见/自己画的时有时无:WebSocket 未升级成功。检查 nginx 是否配了 proxy_http_version 1.1、Upgrade 与 Connection "upgrade" 三件套;云环境还需确认负载均衡层放行 WS。

2. 重连后报 baseline_not_replayable:2.18.31 的重连同步基于操作序号回放,客户端基线序号超出服务端可回放窗口(默认 60 秒内的日志,WBO_SEQ_REPLAY_RETENTION_MS)即拒绝。实测向服务端声明超前基线(baselineSeq=99999)得到连接错误回显:{"data":{"reason":"baseline_not_replayable","latestSeq":0,"minReplayableSeq":0}}。处理:客户端清空本地基线全量拉取;网关层把 WS 空闲超时调大于该保留窗口,从源头减少重连回放失败。

3. 访问 /export、/history 返回 400/404:这是旧版本端点,2.18.31 已移除,导出由前端完成(工具栏下载),自动化导出需驱动无头浏览器,不要写脚本去打这两个 URL。

4. data/ 目录为空、板画完不落文件:确认挂载路径是 /opt/app/server-data(容器内 WBO_HISTORY_DIR 指向它);确认 WBO_SAVE_INTERVAL 未被调得过大;查看 docker compose logs wbo 是否有写盘报错。

5. 子路径部署后页面白屏或资源 404:/wbo/ 前缀剥离由 proxy_pass http://wbo:80/ 的末尾斜杠完成,少写斜杠会把 /wbo/ 原样带给 WBO 导致资源路径错位;若希望 WBO 感知完整前缀,改用服务端 WBO_BASE_PATH(见 C1)。

十、参考链接