World Monitor 本地部署教程:Docker、Ollama、PMTiles 与离线情报面板

World Monitor 自托管教程,覆盖源码运行、Docker 镜像、本地 Ollama、PMTiles 离线底图、外部数据源、缓存、许可证和故障排查。

World Monitor 是一个聚合新闻、市场、航空、地缘风险、基础设施和公开情报数据的实时面板。 它在 GitHub Trending 一周增加约 13,231 stars,但“能打开前端”与“完整离线运行”是两种不同部署目标。 本文先把组件和网络依赖拆开,再给出源码开发、容器前端和本地 AI 摘要三条可验证路径。

先决定要部署到哪一种离线程度

项目文档描述了三类隐私模式。 最简单的是本地打开应用,但继续请求公共 API 和云端 LLM。 第二类是桌面端配合 Ollama、LM Studio、llama.cpp 或 vLLM,让新闻摘要留在本机,其他数据源仍联网。 第三类是隔离网络:本地模型、本地 PMTiles、预先准备的数据快照,并禁用实时外部源。 第三类无法凭一个 Docker 容器自动完成,因为航班、市场、RSS 和风险源本身需要更新。 在动手前写下允许访问的域名、数据更新时间要求和是否允许云端摘要。

World Monitor 的运行组件并不只有网页

前端是 Vanilla TypeScript 应用,地图由 MapLibre GL、deck.gl 和 globe.gl 等组件渲染。 服务端部分包含 Edge handler、RPC 网关、缓存和数据种子任务。 AIS Relay 负责部分实时流与周期数据。 Redis 用于缓存、限流和避免多个请求同时刷新同一数据。 桌面端使用 Tauri,并带有 Node.js sidecar。 PMTiles 可以把底图放到对象存储或局域网 HTTP 服务。 因此,自托管需要明确哪些组件由自己运行,哪些继续借用上游服务。

许可证先于部署方式

仓库采用 AGPL-3.0,并对商业用途有额外说明。 个人、研究和教育用途可以在遵守署名与许可证条件的前提下自托管。 商业 SaaS、去除品牌或重新包装需要查看项目的商业许可要求。 不要把“代码能公开下载”理解成可以无条件闭源销售。 计划对外提供服务时,先阅读仓库中的 LICENSE 和 README 许可表。

准备 Node 22 与基础工具

项目变更记录已把 Node 22 固定为开发基线。 在 Windows 上建议使用 WSL2 Ubuntu,Linux 和 macOS 可直接操作。

1
2
3
4
node --version
npm --version
git --version
make --version

Node 主版本不是 22 时,使用 nvm 切换:

1
2
3
nvm install 22
nvm use 22
node --version

不要在系统 Node 与 nvm Node 之间混用全局包。

从源码启动完整开发面板

先 fork 或直接克隆官方仓库:

1
2
3
git clone https://github.com/koala73/worldmonitor.git
cd worldmonitor
git rev-parse HEAD

保存 commit SHA,后续文档与配置变化都能追溯到明确版本。 官方贡献文档提供了统一安装目标:

1
make install

它会准备 buf、sebuf 插件、npm 依赖和 Playwright 浏览器。 只想查看帮助时运行:

1
make help

完整变体的开发服务器:

1
npm run dev

默认地址是 http://localhost:3000

不同变体不是不同仓库

World Monitor 通过 variant 控制面板、地图层、刷新周期和默认数据源。 技术、金融和完整面板可以分别启动:

1
2
npm run dev:tech
npm run dev:finance

生产构建也有对应命令:

1
2
3
npm run build
npm run build:tech
npm run build:finance

切换 variant 会重置部分设置,不要把不同变体的浏览器 localStorage 当作同一份配置。

环境变量按数据源逐项开启

复制示例文件:

1
cp .env.example .env.local

先不要把所有 API key 一次填满。 从不需要凭据的面板开始,确认前端、地图和基本 RPC 正常。 再逐个增加新闻、市场、航班或 LLM 供应商。 每增加一个变量就重启服务并检查网络请求。 .env.local 不进入 Git:

1
2
git status --short
git check-ignore .env.local

若第二条没有输出,先检查 .gitignore,不要继续填写真实密钥。

Docker 路线适合托管前端

仓库的 docker/Dockerfile 构建多架构镜像,由 nginx 提供 SPA,并把 API 请求代理到上游。 先在本地构建:

1
2
docker build -f docker/Dockerfile -t worldmonitor:local .
docker image inspect worldmonitor:local

查看 Dockerfile 暴露端口和 nginx 配置后再运行,不要猜端口:

1
2
docker image inspect worldmonitor:local \
  --format '{{json .Config.ExposedPorts}}'

假设镜像暴露 80,可用仅回环映射测试:

1
2
3
docker run --rm --name worldmonitor-test \
  -p 127.0.0.1:8080:80 \
  worldmonitor:local

如果实际端口不同,以镜像检查结果为准。

容器前端并不等于所有 API 都本地化

打开浏览器开发者工具的 Network 面板。 刷新页面并按域名分组请求。 任何访问 Vercel、Railway、Upstash、第三方新闻或市场接口的请求,都说明当前仍有云依赖。 不要用“网页来自自己的服务器”推导“数据没有离开局域网”。 需要隔离时,逐项替换 API endpoint,或禁用无法本地运行的面板。

用 Ollama 提供本地摘要

World Monitor 的本地 LLM 路线支持 OpenAI-compatible 服务,并能发现 Ollama、LM Studio、llama.cpp 和 vLLM 模型。 安装 Ollama 后先确认服务:

1
2
3
ollama --version
ollama list
curl http://127.0.0.1:11434/api/tags

拉取一个适合本机资源的指令模型:

1
ollama pull qwen3:8b

再测试 OpenAI 兼容端点:

1
curl http://127.0.0.1:11434/v1/models

应用中把 base URL 指向回环地址,并选择实际存在的模型 ID。

本地 LLM 回退链需要主动验证

项目文档描述的摘要回退顺序包括本地 LLM、Groq、OpenRouter 和浏览器 T5。 如果目标是数据不出网,仅配置 Ollama 不够。 还要移除云端 key,阻止相关域名,并确认浏览器没有在本地超时后静默回退。 把 Ollama 服务停止:

1
sudo systemctl stop ollama

再次触发摘要。 严格离线配置应明确显示本地服务不可用,而不是产生云端摘要。

PMTiles 解决的是底图依赖

传统地图会按视口不断请求在线瓦片。 PMTiles 把瓦片组织为单个归档,可放在本地磁盘、NAS、对象存储或普通 HTTP 服务。 准备文件后先做最小 HTTP 服务:

1
python3 -m http.server 9000 --directory /srv/pmtiles

从浏览器访问 PMTiles 文件,确认支持 Range 请求。 没有 Range 支持时,地图可能尝试下载整个大文件或无法定位瓦片。 反向代理需要保留 RangeAccept-Ranges 相关 Header。

Cloudflare R2 与局域网存储怎么选

R2 适合公网服务,能减轻源站带宽并提供对象级访问。 局域网 MinIO、NAS 或 nginx 更适合隔离环境。 底图文件可能很大,发布前记录尺寸和哈希:

1
2
sha256sum world.pmtiles
du -h world.pmtiles

客户端配置 URL 后,用浏览器确认请求返回 206 Partial Content

Redis 不是本地试用的硬门槛

单人开发可以先不部署完整缓存体系。 多人或公网服务需要 Redis 来控制刷新风暴、缓存 seed 结果和限流。 启动本地 Redis:

1
2
docker run --rm --name worldmonitor-redis \
  -p 127.0.0.1:6379:6379 redis:7-alpine

验证:

1
docker exec worldmonitor-redis redis-cli ping

应返回 PONG。 Redis 不要直接暴露到公网,也不要依赖默认无密码配置跨主机访问。

外部数据源失败时怎样判断责任位置

先检查浏览器请求的 URL、状态码和响应时间。 401403 通常是 key、配额或授权范围。 429 表示速率限制,增加重试可能让问题更严重。 5xx 需要区分自己的代理、上游服务和缓存层。 空数组不一定是故障,也可能是区域和时间范围没有数据。 保存 request ID 和响应 Header,不要只截一张空白面板截图。

AIS 与实时流不能靠静态构建代替

航运 AIS、航班和 GPS 干扰层依赖持续数据流或周期 seed。 纯 nginx SPA 只能展示已有数据和调用上游接口。 需要自托管相关流时,阅读 scripts/ais-relay.cjs 和部署配置,确认数据提供商许可。 不要把公开网页上看到的数据源无条件镜像并重新发布。

开启健康检查与数据新鲜度监控

应用能返回 200,不代表数据在更新。 监控至少分三层:静态页面、API endpoint 和 seed freshness。 记录每个数据源最后成功时间与连续失败次数。 当新闻仍更新而市场停止时,不应把整个站点标成完全健康。

构建前运行项目自己的检查

1
2
3
4
npm run typecheck
npm run test:data
npm run test:e2e
npm run build:full

命令存在性以当前仓库 package.jsonmake help 为准。 数据测试失败时不要删除失败源来让 CI 变绿,先确认格式是否变更。 E2E 需要浏览器依赖和稳定测试数据,容器 CI 要预留共享内存。

反向代理只开放需要的入口

公网部署使用 HTTPS,并把管理端、Redis、Ollama 和内部 seed endpoint 留在私网。 Ollama 默认不应直接暴露到互联网。 若前端与 API 分域,明确设置 CORS 允许列表。 不要使用允许任意 origin 同时携带凭据的组合。

做一次真正的断网演练

加载面板后断开互联网容易得到误判,因为 service worker、浏览器缓存和 IndexedDB 仍保存旧数据。 先清空测试 Profile,阻止外部域名,再重新打开应用。 记录哪些面板正常、哪些显示旧缓存、哪些报错。 检查时间戳是否明确标识数据已经过期。 离线模式应优雅降级,而不是把旧信息伪装成实时信息。

升级时保留 variant 和地图配置

升级前保存 commit、.env.local 变量名、PMTiles URL、Redis schema 和反向代理配置。

1
2
3
git fetch --tags
git log --oneline --decorate -10
git diff -- .env.example docker/ deploy/

先在新工作树构建,不要直接覆盖运行目录。 前端 localStorage 的设置格式可能变化,升级后抽查 variant、图层和刷新周期。

自托管完成的判定清单

  • 页面与所需 variant 可以构建。
  • Docker 镜像端口来自 inspect,而不是猜测。
  • 所有 API key 都在 Git 之外。
  • 本地 LLM 失败时不会静默转到云端。
  • PMTiles 返回 Range 请求。
  • Redis、Ollama 和内部服务不暴露公网。
  • 每个实时数据源都有最后更新时间。
  • 断网测试能区分缓存和真实可用。
  • 商业用途已经核对许可证。

World Monitor 的自托管边界取决于你保留多少实时数据源。先把网络依赖画清楚,再决定是本地前端、隐私摘要还是完整隔离,比直接追求“一条 Docker 命令”更可靠。

项目资料