MC-CartoLive is a single-container public live map for MeshCore MQTT observations. It ingests broker traffic, stores normalized observations in SQLite, resolves only high-confidence RF routes, and serves a privacy-safe MapLibre dashboard for live packet motion, public chat, Packets, NetGraph, Node List, Labs, and optional propagation/terrain context.
Public instance: carto.canadaverse.org.
Version 3.2.2 is the lossless live-flow stabilization patch. It keeps the 3.2
public API, privacy boundary, RF route rules, and schema 32000 while adding:
- fair primary/live-core/background SQLite write coordination and retryable ingest/projection outcomes instead of terminal five-second deadline loss
- short ordered live commits and immediate public broadcasts without a global
cinematic
displayAtreservation - immediate WebSocket state/PacketTV updates plus one adaptive animation-frame scheduler that gives every safely mappable connected-live packet one visual
- cursor recovery and snapshots that reconcile state without replaying stale animation, plus indexed batch route updates under burst load
- privacy-safe queue/projection/broadcast readiness and latency evidence
- mandatory canonical release proof on release-branch and merged-main SHAs, followed by an immutable Canada-digest five-minute canary and consistent-snapshot integrity gate before publication
Published releases run from an immutable GHCR digest through the production Compose package. The repository Compose file remains the local build path.
These are public UI captures from the 3.0 Canada surface.
| Live map overview | Route density | Packet flow replay |
|---|---|---|
| 3.0 live map overview | 3.0 route density view | 3.0 packet flow replay across a route |
| OpenFreeMap 3D terrain |
|---|
| 3.0 OpenFreeMap 3D terrain and RF routes |
| Packets | Chat | Node List |
|---|---|---|
| 3.0 Packets workspace | 3.0 public Chat workspace | 3.0 Node List workspace |
| NetGraph focus | NetGraph overview | Packet Waterfall Labs |
|---|---|---|
| 3.0 NetGraph selected node focus | 3.0 NetGraph connected component overview | 3.0 Packet Waterfall Labs workspace |
- Read-only MQTT ingest with MeshCore packet decoding.
- SQLite persistence under
data/locally or/app/datain the container. - Seven-day raw/event/search retention by default, with compact latest-route summaries retained so the live route graph survives database pruning.
- Conservative public route resolution; ambiguous or unsafe paths are not drawn.
- Public MapLibre dashboard with clusters, nodes, labels, live packet comets, fading trails, message bubbles, route plotting, on-demand packet-path motion, and optional 3D.
- Packets, Chat, NetGraph, Node List, Labs, and propagation history workspaces built from sanitized public data.
- Public-safe health/readiness endpoints and release smoke scripts.
- Worldwide/private broker support through configurable map bounds and region labels.
Credential-free fixture mode is the safest local test path:
cp .env.example .env
podman build --format docker -t mc-cartolive-meshcore-live-map:latest .
podman run --rm --name mc-cartolive -p 39476:8080 --env-file .env mc-cartolive-meshcore-live-map:latestOpen http://127.0.0.1:39476.
The published image can also run the synthetic fixture:
podman run --rm -p 8080:8080 \ -e MQTT_ENABLED=false \ -e PUBLIC_MODE=true \ -e PUBLIC_BASE_URL=http://localhost:8080 \ -e FIXTURE_REPLAY_PATH=/app/examples/fixtures/synthetic-live.ndjson \ ghcr.io/n30nex/mc-cartolive:3.2.2
For a persistent deployment:
podman run -d --name mc-cartolive \ -p 8080:8080 \ --env-file .env \ -v mc-cartolive-data:/app/data \ ghcr.io/n30nex/mc-cartolive:3.2.2
The production droplet currently uses Docker Compose; local release validation uses Podman unless a host is Docker-only.
Start from .env.example. Keep real .env files private.
Important variables:
| Variable | Notes |
|---|---|
PUBLIC_MODE |
Use true for public deployments. |
PUBLIC_BASE_URL |
Must match the public browser origin for WebSocket checks. |
MQTT_ENABLED |
false for fixtures, true for live broker ingest. |
MQTT_USERNAME / MQTT_PASSWORD |
Private broker credentials. Never commit them. |
MESHCORE_CHANNEL_SECRETS |
Optional private extra channel keys for operators. |
FIXTURE_REPLAY_PATH |
Synthetic fixture path for repeatable local demos. |
MAP_REGION_PRESET |
world, canada, or custom. |
VITE_APP_ASSET_PACK |
Build-time frontend asset preset. Generic tags (3.2.2, 3.2, sha-<main-sha>, latest) are world; matching *-canada aliases and the hosted droplet are canada. |
MAP_BOUNDS |
Custom bounds as minLat,minLng,maxLat,maxLng. |
PUBLIC_REGIONS |
Public-safe broker region allowlist. Empty allows safe labels. |
DB_PATH |
SQLite path inside the container. |
SQLITE_READ_OPEN_CONNS |
Read-only SQLite pool size. Production uses 2; the writer remains a single connection. Legacy SQLITE_MAX_OPEN_CONNS is accepted only as a fallback. |
SQLITE_BUSY_TIMEOUT_MS |
Per-attempt SQLite lock wait. Production fixes this to 750 ms; transient failures retry with stable ingest identity and bounded backoff. |
DERIVED_INGEST_QUEUE_SIZE |
Bounded live projection queue. Defaults to 1024; queued work retries instead of being treated as successfully processed. |
METRICS_LISTEN_ADDR |
Dedicated metrics listener. Defaults to 127.0.0.1:9090; Docker publishes it only on host loopback port 39090. |
SQLITE_CACHE_SIZE_KB |
SQLite page cache budget in KiB. Defaults to 16000. |
SQLITE_MMAP_SIZE_BYTES |
SQLite mmap budget in bytes. Defaults to 67108864. |
DATA_RETENTION_DAYS |
Raw packets, observations, live edge events, public history/search rows, and propagation/weather history retention. Defaults to 7; latest public route summaries are preserved separately. |
PUBLIC_EVENT_RETENTION_HOURS |
Public WebSocket-resume event history. Production fixes this to 24. |
ALLOW_UNBOUNDED_RETENTION |
Development escape hatch only. Enabling it in public mode keeps readiness fail-closed. |
PROPAGATION_EVENT_RETENTION_DAYS |
Optional propagation-only override. Defaults to 7. |
VITE_PMTILES_BASEMAP_URL |
Optional same-origin or CSP-allowed PMTiles basemap for offline profiles. |
VITE_PMTILES_TERRAIN_URL |
Reserved optional PMTiles terrain archive URL for future terrain swaps. |
Backend:
cd backend go test ./... go run ./cmd/app
Frontend:
cd web npm ci npm test -- --run npm run build
Release hygiene:
node scripts/check-version-sync.mjs
node scripts/public-schema-check.mjs
node scripts/check-asset-pack.mjs
node scripts/check-frontend-budget.mjs
node scripts/check-public-privacy.mjs http://127.0.0.1:39476
podman build --format docker -t mc-cartolive-meshcore-live-map:latest .
node scripts/package-smoke.mjs --runtime podman --image ghcr.io/n30nex/mc-cartolive:3.2.2 --asset-pack world --pullLive post-deploy smoke:
.\scripts\live-smoke.ps1 -BaseUrl https://carto.canadaverse.org -ExpectedVersion 3.2.2 -ExpectedGitSha <full-sha> -SshTarget root@134.122.45.228 -DiagnoseRegion YTR
- Docs index
- Production deployment
- Development guide
- Operator runbook
- Privacy model
- Roadmap
- Changelog
- 3.2.2 release notes
- 3.2.2 validation checklist
- 3.2.2 storage and stability
- 3.2.2 upgrade and rollback
- 3.2.2 public API notes
- 3.2.2 release verification
- 3.2.0 release errata
- 3.0.2 release notes
- 3.0.2 validation checklist
- 3.0.1 release notes
- 3.0.1 validation checklist
- 3.0.0 release notes
- 3.0.0 screenshot tour
- 3.0.0 asset pack notes
- 3.0.0 validation checklist
- 2.9.6 release notes
- 2.9.5 release notes
- 2.9.4 release notes
- 2.9.3 release notes
Never commit or expose MQTT credentials, MeshCore private keys, channel secrets, live SQLite databases, WAL/SHM files, local operator config, or raw packet captures.
Public APIs must not expose full public keys, observer public keys, packet
hashes, raw payloads, raw path hex, resolver debug reasons, broker secrets, or
private operator config. The only public route-copy identifier is the
six-character MeshCore pathHash3 prefix.