# Meshtastic Stack ## Overview Self-hosted MeshMonitor stack running on PlausibleDeniability, plus the current operator note for the separate NOMAD-side MeshCore companion observer. Related NOMAD-side bridge note: the legacy `mctomqtt` Docker relay was retired on 2026-06-13. N.O.M.A.D. now uses the LetsMesh companion observer flow via `meshcore-capture.service`, running from `/home/fizzlepoof/.meshcore-packet-capture` and connecting directly to the Heltec over `/dev/serial/by-id/...`. Important split: - **PD** hosts the MeshMonitor web/UI stack. - **NOMAD** owns the USB-attached Heltec companion observer via `meshcore-capture.service`. - Do not assume MeshMonitor and the companion observer are the same runtime path. ## Stack Location `/mnt/docker-ssd/docker/compose/meshtastic/` ## Containers | Container | Image | Port | Purpose | |-----------|-------|------|---------| | meshmonitor | ghcr.io/yeraze/meshmonitor:latest | 8081→3001, 4404→4404, 1883→1883 | Main UI + backend; live compose publishes the virtual-node port and embedded MQTT broker directly from this container, and now maps `/dev/ttyACM0` into the container for native MeshCore USB sources | | meshmonitor (virtual node) | — | 4404 | TCP virtual node server exposed directly by the meshmonitor container | | meshmonitor (embedded MQTT broker) | — | 1883 | Embedded Aedes-based MQTT broker exposed directly by the meshmonitor container | | meshmonitor-tileserver | maptiler/tileserver-gl-light:latest | 8082→8080 | Offline map tiles | | meshmonitor-upgrader | docker:latest | — | Auto-upgrade watchdog | Live runtime verified on 2026-07-03: - `docker compose ps` on PD showed `meshmonitor`, `meshmonitor-tileserver`, and `meshmonitor-upgrader` running. - Repo compose and live runtime now agree that there is no separate `meshmonitor-mqtt-proxy` sidecar in the active stack. - The embedded MQTT broker source `Meshcore Peachtree Observer` is configured in MeshMonitor and logs `MQTT broker listening on 0.0.0.0:1883`. - A native MeshCore USB source `PT Meshcore` is now auto-connected in MeshMonitor via `/dev/ttyACM0` after the compose file was updated to map the device into the container. - NOMAD `meshcore-capture.service` was later returned to its three upstream brokers after the embedded-broker test path proved unnecessary for real MeshCore ingestion. ## Architecture ``` Trusted-LAN mesh node (10.5.1.120) ↓ direct node connection configured by MESHTASTIC_NODE_IP meshmonitor backend on PD ↓ PostgreSQL (shared-postgres, db: meshmonitor) Separate path: NOMAD Heltec companion observer (`meshcore-capture.service`) ↓ upstream MQTT brokers (LetsMesh US / EU + NashMe) PD native MeshCore USB source (`PT Meshcore`) ↓ `/dev/ttyACM0` mapped into the meshmonitor container ↓ meshcore.js native companion backend ``` Note: the embedded MeshMonitor broker now accepts the NOMAD connection on `10.5.30.6:1883`, but current MeshMonitor logs still show protobuf decode warnings for MeshCore packet payloads. Treat this as confirmed broker fanout connectivity, not yet confirmed first-class MeshCore ingestion. ## Node Connection - PD MeshMonitor compose is currently configured with `MESHTASTIC_NODE_IP=10.5.1.120` - MeshMonitor itself publishes port `4404` for the virtual-node path and `1883` for the embedded MQTT broker; there is no separate `meshmonitor-mqtt-proxy` service in the active stack - For native MeshCore USB sources on PD, the live compose now maps `/dev/ttyACM0` directly into the `meshmonitor` container - NOMAD's companion observer is a different ingest path and should not be documented as a MeshMonitor sidecar ## Storage - Appdata: `/mnt/tank/docker/appdata/meshmonitor/data` → `/data` - Scripts: `./scripts` → `/data/scripts` (must be pre-created on host) - Tiles: `./tiles` (gitignored — large .mbtiles files) ## Auto-Upgrade `AUTO_UPGRADE_ENABLED=true` — meshmonitor checks for new images and triggers self-upgrade. **Important:** The upgrader mounts the compose directory as `/compose` inside the container. All relative bind mount paths (e.g. `./scripts`) resolve to `/compose/scripts` on the host when the upgrader re-runs compose. Since TrueNAS root filesystem is read-only, these directories must be pre-created: ```bash mkdir -p /mnt/docker-ssd/docker/compose/meshtastic/scripts ``` ## Networks - `default` (internal stack network) - `ix-databases_shared-databases` (meshmonitor only) - `pangolin` (meshmonitor + tileserver) ## Public URL `https://meshmonitor.paccoco.com` ## Known Warnings - Node `!dd972536` has a low-entropy public key — this is a device configuration issue, not a meshmonitor bug - MeshMonitor logs can still show noisy reconnect/admin-session churn during node or radio instability; do not confuse that with the retired NOMAD `mctomqtt` path ## Tiles Map tiles stored in `./tiles/`. Currently includes `zurich_switzerland.mbtiles` (34MB). Tiles directory is gitignored. To add new tiles, download `.mbtiles` files and place in the `tiles/` directory. ## TODO - [ ] Document all running meshtastic-map container config - [ ] Add healthcheck to meshmonitor container