World Monitor 本機部署教學:Docker、Ollama、PMTiles 與離線情報面板

從原始碼或 Docker 自架 World Monitor,串接 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 命令”更可靠。

專案資料