Add observer Docker Compose setup and update README instructions

Add contrib/packetcapture/ with ready-made docker-compose.yml and .env.example
for remote observers. Parameterize MQTT port and TLS for local network use.
Rewrite README observer section with wget-based setup workflow.
This commit is contained in:
Louis King
2026-04-19 21:47:57 +01:00
parent 19ac2f8aa1
commit 710263b248
3 changed files with 147 additions and 33 deletions
+29 -33
View File
@@ -220,43 +220,39 @@ Other operators can run their own [meshcore-packet-capture](https://github.com/a
#### Example: Observer contributing to LetsMesh and your community Hub
```bash
# In the observer's .env or docker-compose environment:
# Server 1 - Let's Mesh US (opt-in)
PACKETCAPTURE_MQTT1_ENABLED=true
PACKETCAPTURE_MQTT1_SERVER=mqtt-us-v1.letsmesh.net
PACKETCAPTURE_MQTT1_PORT=443
PACKETCAPTURE_MQTT1_TRANSPORT=websockets
PACKETCAPTURE_MQTT1_USE_TLS=true
PACKETCAPTURE_MQTT1_USE_AUTH_TOKEN=true
PACKETCAPTURE_MQTT1_TOKEN_AUDIENCE=mqtt-us-v1.letsmesh.net
# Server 2 - Let's Mesh EU (opt-in)
PACKETCAPTURE_MQTT2_ENABLED=false
# Server 3 - Your MeshCore Hub
PACKETCAPTURE_MQTT3_ENABLED=true
PACKETCAPTURE_MQTT3_SERVER=mqtt.example.com
PACKETCAPTURE_MQTT3_PORT=443
PACKETCAPTURE_MQTT3_TRANSPORT=websockets
PACKETCAPTURE_MQTT3_USE_TLS=true
PACKETCAPTURE_MQTT3_USE_AUTH_TOKEN=true
PACKETCAPTURE_MQTT3_TOKEN_AUDIENCE=mqtt.example.com
```
Replace `mqtt.example.com` with your public MQTT domain. The `TOKEN_AUDIENCE` must match the `MQTT_TOKEN_AUDIENCE` or `AUTH_EXPECTED_AUDIENCE` configured on your broker.
For local network observers (no TLS):
A ready-made Docker Compose setup is provided in `contrib/packetcapture/`. Download it and configure:
```bash
PACKETCAPTURE_MQTT3_SERVER=192.168.1.100
PACKETCAPTURE_MQTT3_PORT=1883
PACKETCAPTURE_MQTT3_TRANSPORT=websockets
PACKETCAPTURE_MQTT3_USE_TLS=false
PACKETCAPTURE_MQTT3_TOKEN_AUDIENCE=mqtt.localhost
mkdir meshcore-observer && cd meshcore-observer
wget https://raw.githubusercontent.com/ipnet-mesh/meshcore-hub/main/contrib/packetcapture/docker-compose.yml
wget https://raw.githubusercontent.com/ipnet-mesh/meshcore-hub/main/contrib/packetcapture/.env.example
cp .env.example .env
```
Edit `.env` and update the following variables:
| Variable | Description |
|----------|-------------|
| `SERIAL_PORT` | Device path for your Meshtastic device (e.g. `/dev/ttyUSB0`, or `/dev/serial/by-id/...` for a stable path) |
| `IATA` | 3-letter area code for your location (e.g. `STN`, `SEA`) |
| `ORIGIN` | Observer identifier (default: `observer`) |
| `ENABLE_LETSMESH_US` | Set `true` to contribute to LetsMesh US |
| `ENABLE_LETSMESH_EU` | Set `true` to contribute to LetsMesh EU |
| `CUSTOM_MQTT_HOST` | Your community Hub's public MQTT domain (e.g. `mqtt.example.com`) |
| `CUSTOM_MQTT_PORT` | MQTT port — `443` for TLS/WSS, `1883` for local/plain |
| `CUSTOM_MQTT_TLS` | `true` for TLS, `false` for plain connections |
| `CUSTOM_MQTT_AUDIENCE` | Must match `MQTT_TOKEN_AUDIENCE` on your broker (e.g. `mqtt.example.com` for TLS, `mqtt.localhost` for local) |
Then start the observer:
```bash
docker compose up -d
```
> **Local network (no TLS):** Set `CUSTOM_MQTT_HOST` to the Hub's LAN IP (e.g. `192.168.1.100`), `CUSTOM_MQTT_PORT=1883`, `CUSTOM_MQTT_TLS=false`, and `CUSTOM_MQTT_AUDIENCE=mqtt.localhost`.
### Backup & Restore
#### Using Makefile
+69
View File
@@ -0,0 +1,69 @@
# ==========================================================================
# MeshCore Packet Capture - Observer Configuration
# ==========================================================================
# Copy this file to .env and update the values below.
#
# This observer captures MeshCore mesh traffic from a serial device and
# forwards decoded packets to one or more MQTT brokers. By default it sends
# to your community Hub and optionally to the LetsMesh network (US/EU).
#
# Prerequisites:
# - A Meshtastic device connected via USB (or modify CONNECTION_TYPE for network)
# - Your community Hub's MQTT broker must be accessible (WSS with TLS recommended)
#
# Quick start:
# cp .env.example .env # then edit .env
# docker compose up -d
# ==========================================================================
# ---------------------------------------------------------------------------
# Serial / Device
# ---------------------------------------------------------------------------
# Path to your Meshtastic device. Use /dev/serial/by-id/... for a stable path
# that survives reboots (avoids /dev/ttyUSB0 reordering).
# Find your device: ls /dev/serial/by-id/
SERIAL_PORT=/dev/ttyUSB0
# ---------------------------------------------------------------------------
# Identity
# ---------------------------------------------------------------------------
# 3-letter IATA airport code for your area (e.g. STN, SEA, LAX, AMS).
# Used as a location tag in MQTT topic paths.
IATA=STN
# Observer name/identifier. Appears in packet metadata.
ORIGIN=observer
# ---------------------------------------------------------------------------
# Schedule
# ---------------------------------------------------------------------------
# Hours between self-advertisement broadcasts (default: 11).
ADVERT_INTERVAL_HOURS=11
# ---------------------------------------------------------------------------
# LetsMesh (optional)
# ---------------------------------------------------------------------------
# Contribute captured packets to the LetsMesh network.
# Enable one or both servers to share data for the public mesh map.
# See https://letsmesh.net for more info.
ENABLE_LETSMESH_US=false
ENABLE_LETSMESH_EU=true
# ---------------------------------------------------------------------------
# Community Hub MQTT Broker (required)
# ---------------------------------------------------------------------------
# Your community MeshCore Hub's MQTT broker. Captured packets are sent here
# for your local network dashboard.
#
# TLS (production / reverse proxy):
CUSTOM_MQTT_HOST=mqtt.example.com
CUSTOM_MQTT_PORT=443
CUSTOM_MQTT_TLS=true
# CUSTOM_MQTT_AUDIENCE must match the MQTT_TOKEN_AUDIENCE on your broker
CUSTOM_MQTT_AUDIENCE=mqtt.example.com
# Local network (no TLS) — uncomment and adjust these instead:
# CUSTOM_MQTT_HOST=192.168.1.100
# CUSTOM_MQTT_PORT=1883
# CUSTOM_MQTT_TLS=false
# CUSTOM_MQTT_AUDIENCE=mqtt.localhost
+49
View File
@@ -0,0 +1,49 @@
services:
meshcore-packet-capture:
image: ghcr.io/agessaman/meshcore-packet-capture:latest
container_name: meshcore-packet-capture
devices:
- ${SERIAL_PORT:-/dev/ttyUSB0}
group_add:
- dialout
volumes:
- data:/app/data
environment:
- PACKETCAPTURE_CONNECTION_TYPE=${CONNECTION_TYPE:-serial}
- PACKETCAPTURE_SERIAL_PORTS=${SERIAL_PORT:-/dev/ttyUSB0}
# MQTT Broker 1 - Let'sMesh Analyzer (US)
- PACKETCAPTURE_MQTT1_ENABLED=${ENABLE_LETSMESH_US:-false}
- PACKETCAPTURE_MQTT1_SERVER=mqtt-us-v1.letsmesh.net
- PACKETCAPTURE_MQTT1_PORT=443
- PACKETCAPTURE_MQTT1_TRANSPORT=websockets
- PACKETCAPTURE_MQTT1_USE_TLS=true
- PACKETCAPTURE_MQTT1_USE_AUTH_TOKEN=true
- PACKETCAPTURE_MQTT1_TOKEN_AUDIENCE=mqtt-us-v1.letsmesh.net
- PACKETCAPTURE_MQTT1_KEEPALIVE=120
# MQTT Broker 2 - Let'sMesh Analyzer (EU)
- PACKETCAPTURE_MQTT2_ENABLED=${ENABLE_LETSMESH_EU:-false}
- PACKETCAPTURE_MQTT2_SERVER=mqtt-eu-v1.letsmesh.net
- PACKETCAPTURE_MQTT2_PORT=443
- PACKETCAPTURE_MQTT2_TRANSPORT=websockets
- PACKETCAPTURE_MQTT2_USE_TLS=true
- PACKETCAPTURE_MQTT2_USE_AUTH_TOKEN=true
- PACKETCAPTURE_MQTT2_TOKEN_AUDIENCE=mqtt-eu-v1.letsmesh.net
- PACKETCAPTURE_MQTT2_KEEPALIVE=120
# IPNet MQTT Broker
- PACKETCAPTURE_MQTT3_ENABLED=true
- PACKETCAPTURE_MQTT3_SERVER=${CUSTOM_MQTT_HOST}
- PACKETCAPTURE_MQTT3_PORT=${CUSTOM_MQTT_PORT:-443}
- PACKETCAPTURE_MQTT3_TRANSPORT=websockets
- PACKETCAPTURE_MQTT3_USE_TLS=${CUSTOM_MQTT_TLS:-true}
- PACKETCAPTURE_MQTT3_USE_AUTH_TOKEN=true
- PACKETCAPTURE_MQTT3_TOKEN_AUDIENCE=${CUSTOM_MQTT_AUDIENCE}
- PACKETCAPTURE_MQTT3_KEEPALIVE=120
# Area/Origin
- PACKETCAPTURE_IATA=${IATA}
- PACKETCAPTURE_ORIGIN=${ORIGIN:observer}
# Schedule/Timeouts
- PACKETCAPTURE_ADVERT_INTERVAL_HOURS=${ADVERT_INTERVAL_HOURS:-11}
restart: unless-stopped
volumes:
data: