Ubuntu 22.04 安装 Nullboard 2023.11.05 指南

Ubuntu 22.04 从零部署 Nullboard:Nginx 静态托管与 http.server 备用方案、nbagent 备份后端 pip/离线安装与 systemd 托管、浏览器配对验证与 FAQ,全程实测。

Nullboard看板自托管2026/10/24

Ubuntu 22.04 安装 Nullboard 2023.11.05 指南

目标:在一台 Ubuntu 22.04 服务器上从零部署 Nullboard 看板:Nginx 静态托管主页面 + nbagent 备份后端(systemd 托管),并在浏览器中完成配对验证。全部命令与回显均在 Ubuntu 22.04(Nginx 1.18.0、Python 3.10.12、nbagent 1.1.0)环境实测通过。

一、环境信息

本文实测环境与关键路径如下,读者按同样口径操作可获得一致结果:

项目取值
操作系统Ubuntu 22.04(PRETTY_NAME="Ubuntu 22.04.5 LTS")
Nullboard 版本master 分支 nullboard.html,codeVersion 20231105(文件 105597 字节,md5 1d497f06618e9d0697033c159daf6bf9)
Nginx1.18.0(Ubuntu 官方仓库 apt 版)
Python3.10.12(Ubuntu 22.04 自带 python3)
nbagent1.1.0(PyPI,Nullboard 备份协议的 Unix 实现)
主页面目录/var/www/nullboard/
Nginx 站点配置/etc/nginx/sites-available/nullboard
备份 Agent 监听0.0.0.0:10001
备份数据目录/var/lib/nbagent/
systemd 单元/etc/systemd/system/nbagent.service

说明:Nullboard 本体是单 HTML 文件,无后端进程;真正常驻的只有 Nginx(静态托管)与 nbagent(备份落盘)两个角色,前者必须装,后者按需选装(不装则只能手动导出 .nbx 文件备份)。

二、前置条件

开始安装前,确认以下条件已满足:

  1. 一台可登录的 Ubuntu 22.04 服务器,具有 root 或 sudo 权限(本文以 root 演示);
  2. 服务器能访问外网(下载 nullboard.html 与 pip 包);离线服务器参见第六章离线方案;
  3. 80 端口(页面)与 10001 端口(备份 Agent)未被占用,可用以下命令确认:
ss -ltn | grep -E ':80 |:10001'

本机实测(端口空闲时该命令无输出,即两个端口都未被占用,可继续):

若已有输出(端口被占),将后文对应端口改掉即可(Nginx 改 listen,nbagent 改 --port)。

  1. 更新软件源索引:
apt-get update

实测回显(节选末尾):

Get:6 http://archive.ubuntu.com/ubuntu jammy-updates/universe amd64 Packages [1628 kB]
Fetched 6515 kB in 7s (991 kB/s)
Reading package lists...
  1. 安装基础工具 Nginx、pip 与 curl(curl 用于下载与验证):
DEBIAN_FRONTEND=noninteractive apt-get install -y nginx python3-pip curl

实测回显(节选末尾):

Setting up publicsuffix (20211207.1025-1) ...
Processing triggers for libc-bin (2.35-0ubuntu3.15) ...

验证版本:

nginx -v
python3 -V

实测回显:

nginx version: nginx/1.18.0 (Ubuntu)
Python 3.10.12

三、版本选型说明

Nullboard 没有语义化版本号与 Release tag,官方以「changelog 日期 + 代码内 codeVersion」标记演进。选型口径如下:

项目当前口径(查询日期 2026-10-24)说明
Nullboard 主文件master 分支 nullboard.html,codeVersion 20231105与官方 changelog(nullboard.io/changes)最新条目 2023.11.05 一致;文件 105597 字节
官方 Windows Agentnb-agent.exe Ver 0.1(nullboard.io/backups 官方下载)仅 Windows 托盘程序,不适用于 Linux 服务器
Linux 备份 Agentnbagent 1.1.0(PyPI,luismedel/nbagent)Python 实现,备份协议与官方 Agent 相同,pip install nbagent 即得

如何选择:主文件固定取 master 分支最新版即可(无历史版本可挑,升级=重新下载覆盖);Linux 服务器备份后端选 nbagent 1.1.0(PyPI 最新稳定版,requires-python >= 3.8)。

获取主文件最新版本号的验证方法(下载后在本文件内确认 codeVersion):

grep -o 'codeVersion: [0-9]*' /var/www/nullboard/nullboard.html

实测回显:

codeVersion: 20231105,

四、方案 A:Nginx 静态托管(推荐,生产固定入口)

方案 A 用 Nginx 把 nullboard.html 挂成一个固定站点,适合内网自托管、长期使用的场景。流程:创建站点目录 → 下载主文件 → 配置站点 → 启动 Nginx → 验证。

4.1 创建站点目录并下载主文件

mkdir -p /var/www/nullboard
curl -sfL https://raw.githubusercontent.com/apankrat/nullboard/master/nullboard.html \
     -o /var/www/nullboard/nullboard.html

⚠️ 若服务器访问 GitHub 缓慢或超时,可改走 HTTP 代理下载(代理地址按实际环境替换):

curl -sfL -x http://192.168.1.62:7897 \
     https://raw.githubusercontent.com/apankrat/nullboard/master/nullboard.html \
     -o /var/www/nullboard/nullboard.html

验证文件落地与完整性:

ls -la /var/www/nullboard/nullboard.html
md5sum /var/www/nullboard/nullboard.html

实测回显:

-rw-r--r-- 1 root root 105597 Oct 24 01:12 /var/www/nullboard/nullboard.html
1d497f06618e9d0697033c159daf6bf9  /var/www/nullboard/nullboard.html

说明:105597 字节即单文件应用的全部体积;md5 随上游更新会变化,校验要点是「字节数在 10 万级、内容以 <!doctype html> 开头」,可用 head -c 200 /var/www/nullboard/nullboard.html 确认。

4.2 配置 Nginx 站点

写入站点配置(默认 80 端口,root 指向站点目录,默认首页设为 nullboard.html):

cat > /etc/nginx/sites-available/nullboard <<'EOF'
server {
    listen 80 default_server;
    listen [::]:80 default_server;
    root /var/www/nullboard;
    index nullboard.html;
    server_name _;
}
EOF

配置逐项说明:

  • listen 80 default_server / listen [::]:80 default_server:IPv4 与 IPv6 的 80 端口,作为本机默认站点(访问 IP 即可达);
  • root /var/www/nullboard:站点根目录,nullboard.html 所在位置;
  • index nullboard.html:默认首页文件,访问 / 时直接返回看板页面;
  • server_name _:匹配任意主机名/纯 IP 访问。

启用站点并移除默认示例站点(避免 default_server 冲突):

rm -f /etc/nginx/sites-enabled/default
ln -sf /etc/nginx/sites-available/nullboard /etc/nginx/sites-enabled/nullboard
nginx -t

实测回显:

nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

4.3 启动 Nginx 并设置开机自启

systemctl start nginx
systemctl enable nginx
systemctl is-active nginx

实测回显(逐条命令对应):

systemctl start/enable 成功时无输出;最后一条 is-active 输出:

active

4.4 验证页面可达

curl -sI http://127.0.0.1/
ss -ltn | grep -E ':80 '

实测回显:

HTTP/1.1 200 OK
Server: nginx/1.18.0 (Ubuntu)
Date: Sat, 24 Oct 2026 01:22:49 GMT
Content-Type: text/html
Content-Length: 105597
Last-Modified: Sat, 24 Oct 2026 01:12:43 GMT

LISTEN 0      511          0.0.0.0:80         0.0.0.0:*
LISTEN 0      511             [::]:80            [::]:*

结果确认:HTTP 200 且 Content-Length 与文件大小 105597 一致,即页面托管成功。此时用浏览器访问 http://<服务器IP>/ 即可使用 Nullboard(数据存于各访问者浏览器 localStorage)。

⚠️ 服务器配置了 http_proxy 环境变量时,curl 对 127.0.0.1 的请求可能被代理拦截返回 502,验证时加 --noproxy "*" 或改用浏览器访问。该坑在本机实测中真实出现过(详见第九章 FAQ Q3)。

五、方案 B:Python http.server 轻量托管(备用,临时/离线场景)

方案 B 不装 Nginx,直接用 Ubuntu 自带的 Python3 起 SimpleHTTP 服务托管站点目录,适合临时演示、验收测试或不想引入 Nginx 的极简场景。它无需任何安装步骤(Python 3 是 Ubuntu 22.04 自带组件),但官方定位是自测用途,不建议长期对外服务。

在站点目录下启动(8080 端口为例,避免与其他服务冲突):

cd /var/www/nullboard
nohup python3 -m http.server 8080 --bind 0.0.0.0 >/var/log/nullboard-http.log 2>&1 &

验证可达性:

curl -sI http://127.0.0.1:8080/nullboard.html | head -5

实测回显:

HTTP/1.0 200 OK
Server: SimpleHTTP/0.6 Python/3.10.12
Date: Sat, 24 Oct 2026 01:22:06 GMT
Content-type: text/html
Content-Length: 105597

结果确认:HTTP 200、Content-Length 一致即托管成功,浏览器访问 http://<服务器IP>:8080/nullboard.html 使用。

停止临时服务:

pkill -f 'http.server 8080'

要点:nohup ... & 方式退出登录后进程仍在,但不随开机自启、无崩溃拉起;若要长期用方案 B,应仿照第七章把该命令写成 systemd 单元(ExecStart=/usr/bin/python3 -m http.server 8080 --bind 0.0.0.0 --directory /var/www/nullboard,Python 3.7+ 支持 --directory,可省去 cd)。

六、方案对比与离线安装补充

6.1 两种托管方案对比

维度方案 A:Nginx方案 B:http.server
需安装软件Nginx(apt)无(Python 3 自带)
默认端口808080(自定)
进程管理systemd(随开机自启、崩溃监控)手工 nohup,需自写成 systemd 才等价
日志/var/log/nginx/access.log、error.log重定向文件(本文 /var/log/nullboard-http.log)
适用场景生产/长期内网服务(推荐)临时演示、验收、快速验证

选择建议:可联网长期使用选方案 A;离线电脑/一次性演示选方案 B。两方案可以共存(不同端口),用 Nginx 反代到 http.server 也可行,但对单文件应用无必要。

6.2 离线安装 nbagent(wheel 包离线分发)

在能联网的机器上把 nbagent 及其全部依赖下载成 wheel 包,再拷贝到离线服务器安装。联网机器执行:

pip3 download nbagent -d /root/nbagent-wheels

实测回显(-q 静默模式无进度输出,产物清单):

Flask_Cors-4.0.0-py2.py3-none-any.whl
blinker-1.9.0-py3-none-any.whl
click-8.1.7-py3-none-any.whl
flask-2.3.3-py3-none-any.whl
itsdangerous-2.2.0-py3-none-any.whl
jinja2-3.1.6-py3-none-any.whl
markupsafe-3.0.4-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl
nbagent-1.1.0-py3-none-any.whl
werkzeug-3.1.9-py3-none-any.whl

说明:共 9 个 wheel,其中 markupsafe 是按 CPython 3.10 x86_64 编译的平台包,离线目标机需同为 Python 3.10 x86_64(Ubuntu 22.04 默认满足);其余为纯 Python 包无平台限制。

把整个目录拷到离线服务器后,用「不访问索引、只找本地包」方式安装(本机用 venv 环境实测验证过该方式可用):

python3 -m venv /opt/nbagent-venv
/opt/nbagent-venv/bin/pip install --no-index --find-links=/root/nbagent-wheels nbagent
/opt/nbagent-venv/bin/nbagent --help

实测回显(安装 -q 静默,--help 首行节选):

Usage: nbagent [OPTIONS]

  A Nullboard backup agent

结果确认:--help 正常输出即离线安装成功。此时 systemd 单元中 ExecStart 应改为 /opt/nbagent-venv/bin/nbagent。

七、备份后端 nbagent 安装与 systemd 托管

Nullboard 的看板数据存于浏览器 localStorage,自动备份需要一个落盘的伴生服务。Linux 服务器选装 nbagent(Python 实现的 Nullboard Backup Agent,协议与官方 Windows 版一致)。

7.1 pip 安装

pip3 install nbagent

实测回显(节选末尾):

Installing collected packages: MarkupSafe, itsdangerous, click, blinker, Werkzeug, Jinja2, Flask, Flask-Cors, nbagent
Successfully installed Flask-2.3.3 Flask-Cors-4.0.0 Jinja2-3.1.6 MarkupSafe-3.0.4 Werkzeug-3.1.9 blinker-1.9.0 click-8.1.7 itsdangerous-2.2.0 nbagent-1.1.0
WARNING: Running pip as the 'root' user can result in broken permissions and conflicting behaviour with the system package manager. It is recommended to use a virtual environment instead: https://pip.pypa.io/warnings/venv

⚠️ root 用户直接 pip 装系统级 Python 包会收到如上 WARNING,属正常提示可忽略;介意者用 6.2 节的 venv 方式安装。

确认安装结果:

pip3 show nbagent | head -4
which nbagent

实测回显:

Name: nbagent
Version: 1.1.0
Summary: A Nullboard backup agent for Unix systems
Home-page:
/usr/local/bin/nbagent

7.2 首次运行与 Access Token

先手动试运行一次,确认服务能起并拿到自动生成的 Access Token:

timeout 4 nbagent; true

实测回显:

 * [i] Using data directory /root/.local/share/nbagent
 * [i] Config saved to /root/.local/share/nbagent/app-config.json
 * [!] Nullboard token: 23d650c082c2433192b8d817dbf55b06
 * [i] Server listening 0.0.0.0:10001...
 * Serving Flask app 'nbagent.main'
 * Debug mode: off

回显解读:

  • Using data directory:数据目录,默认 $HOME/.local/share/nbagent(遵循 XDG_DATA_HOME);
  • Nullboard token:配对用的 Access Token,每次初始化随机生成,读者实测时是不同的随机值,属正常现象;
  • Server listening 0.0.0.0:10001:默认监听地址端口。

试运行会在默认目录留下初始化产物(app-config.json 与 boards/、deleted/ 子目录)。本章后续用服务器级目录 /var/lib/nbagent 重新初始化,默认目录可留作试运行记录或 rm -rf /root/.local/share/nbagent 清理。

7.3 写入 systemd 单元

cat > /etc/systemd/system/nbagent.service <<'EOF'
[Unit]
Description=Nullboard Backup Agent (nbagent)
After=network.target

[Service]
Type=simple
ExecStart=/usr/local/bin/nbagent --addr 0.0.0.0 --port 10001 --data /var/lib/nbagent
Restart=on-failure
RestartSec=3

[Install]
WantedBy=multi-user.target
EOF

单元逐项说明:

  • After=network.target:网络就绪后再启动;
  • ExecStart:以 --data /var/lib/nbagent 指定服务器级数据目录(生产比 $HOME 路径更规范,便于备份该目录本身);
  • Restart=on-failure + RestartSec=3:异常退出 3 秒后自动拉起;
  • WantedBy=multi-user.target:多用户运行级自启。

(若采用 6.2 节 venv 离线安装,把 ExecStart 的路径改为 /opt/nbagent-venv/bin/nbagent。)

加载并启用:

systemctl daemon-reload
systemctl enable nbagent
systemctl start nbagent
systemctl is-active nbagent
systemctl is-enabled nbagent

实测回显:

Created symlink /etc/systemd/system/multi-user.target.wants/nbagent.service → /etc/systemd/system/nbagent.service.
active
enabled

结果确认:is-active 与 is-enabled 均为正向输出,服务已常驻并开机自启。

7.4 获取配对 Token 并验证服务

查看新数据目录下生成的 token:

cat /var/lib/nbagent/app-config.json
journalctl -u nbagent --no-pager -n 3
ss -ltn | grep 10001

实测回显:

{
  "auth": "46f95cf448a24a96b1f4c7c7ed5eb369"
}
Oct 24 01:13:51 nullboard-server systemd[1]: Started Nullboard Backup Agent (nbagent).
LISTEN 0      128          0.0.0.0:10001      0.0.0.0:*

结果确认:app-config.json 的 auth 字段即配对 Token(本文实测值为 46f95cf448a24a96b1f4c7c7ed5eb369,读者环境为不同随机值),10001 端口已监听。

7.5 浏览器配对自动备份

在能访问该服务器的浏览器中完成 Nullboard 与 Agent 的配对:

  1. 打开 http://<服务器IP>/(Nginx 方案);
  2. 右上角菜单 → Auto-backups;
  3. Enable backup:Remote backup(或 Local backup,取决于 Nullboard 看到的 Agent 地址)填入 http://<服务器IP>:10001 与上一步的 Access Token;
  4. 点 Check the setup,显示通过后 Save;
  5. 配对成功后菜单符号变为备份状态图标,且 /var/lib/nbagent/boards/ 下开始出现以看板内部 ID 命名的子目录(如 1618401166671/,内含 meta.json 与 rev-00000000.json 等修订文件)。

💡 说明:Check the setup 实际就是向 Agent 发一次 PUT /config 探测请求;备份协议的四个接口(checkStatus/saveConfig/saveBoard/nukeBoard)可用 curl 直接实测,完整请求/响应示例见《Nullboard Agent 常用 CLI 命令与工具详解》。

八、升级与多实例说明

  • 主页面升级:重新下载 master 分支 nullboard.html 覆盖 /var/www/nullboard/nullboard.html 即可,无需重启 Nginx(静态文件即时生效);升级前建议 cp nullboard.html nullboard.html.bak-<日期> 留底。
  • 备份 Agent 升级:pip3 install --upgrade nbagent 后 systemctl restart nbagent;数据目录格式向后兼容,无需迁移。
  • 多实例:nbagent 可按端口起多份(不同 --port 与 --data,各自独立 token 与目录),对应多个 systemd 单元文件即可;主页面本身无实例概念,一个静态目录即一个站点。

九、常见问题(FAQ)

Q1:apt-get install 时报 404 或依赖失败? 先 apt-get update 刷新索引再装(Ubuntu 22.04 最小安装后索引可能为空);仍失败检查 /etc/apt/sources.list 是否为 jammy 源。

Q2:浏览器打开页面空白或 404? 依次检查:systemctl is-active nginx 是否 active;curl -sI http://127.0.0.1/ 是否 200;/etc/nginx/sites-enabled/ 下是否启用了 nullboard 且移除了 default(default_server 只能有一个);文件是否在 root 指向的目录且名为 nullboard.html。

Q3:本机 curl 验证返回 502,但页面在浏览器里正常? 本机实测真实遇到过:环境变量 http_proxy/https_proxy 指向了代理服务器,curl 对 127.0.0.1 的请求也被发给代理,代理无法回源内网地址遂回 502。解决:验证命令加 --noproxy "*",或在环境里补 export no_proxy=127.0.0.1,localhost。浏览器通常不受该变量影响,故出现「curl 502、浏览器正常」的组合。

Q4:nbagent 启动即退出,journalctl 报端口占用? 10001 被其他进程占用时 Flask 会抛异常退出(systemd 按重启策略反复拉起)。ss -ltnp | grep 10001 找到占用进程,或改 unit 中 --port 换端口,改完 systemctl daemon-reload && systemctl restart nbagent。

Q5:配对时 Check the setup 失败? 三个常见原因:Token 粘贴错误(注意不含空格/换行);Agent 地址填错(必须是与浏览器同网络可达的地址,本机浏览器访问服务器填服务器 IP 而非 127.0.0.1);防火墙未放行 10001(ufw allow 10001/tcp 或云安全组规则)。可用 curl 从浏览器所在机器直接探测:curl -X PUT http://<服务器IP>:10001/config -H "X-Access-Token: <token>" -d "self=test",返回 true 即协议层已通。

Q6:清了浏览器缓存/换了浏览器,看板数据没了? localStorage 按浏览器+站点隔离,清站点数据即丢。恢复途径二选一:打开 Auto-backups 里配置过的 Agent,看板会从备份恢复;或用此前导出的 .nbx 文件走「Import board」。预防措施:部署 nbagent 开自动备份(第七章)。

Q7:pip 装完 nbagent 命令找不到? pip 脚本目录不在 PATH 时会发生。python3 -m pip show nbagent 确认已装,find / -name nbagent -type f 2>/dev/null 定位实际路径(常见 /usr/local/bin/nbagent),或改用 venv 安装方式(6.2 节)。

十、卸载与清理

按角色卸载,互不影响:

systemctl disable nbagent
systemctl stop nbagent
rm -f /etc/systemd/system/nbagent.service
systemctl daemon-reload
pip3 uninstall -y nbagent
rm -rf /var/lib/nbagent /root/.local/share/nbagent

(备份 Agent 部分实测:disable 输出 Removed "/etc/systemd/system/multi-user.target.wants/nbagent.service".,stop 与后续清理命令成功无输出,systemctl is-active nbagent 回显 inactive。)

静态站点部分:

rm -f /etc/nginx/sites-enabled/nullboard /etc/nginx/sites-available/nullboard
rm -rf /var/www/nullboard
nginx -t && systemctl reload nginx

若 Nginx 本身也不需要了:apt-get purge -y nginx && apt-get autoremove -y。

十一、参考链接