Using meshtasticd β
meshtasticd runs Meshtastic firmware on Linux using portduino. It supports both simulated virtual nodes (no hardware needed) and physical LoRa radios connected via USB.
What is meshtasticd? β
meshtasticd provides a software Meshtastic node that can run with or without physical LoRa hardware.
Use cases include:
- Testing MeshMonitor without physical hardware (use
-sflag) - Running node software with a real LoRa radio on a server or Raspberry Pi (omit
-s) - Developing and testing mesh applications
- Creating virtual mesh networks for simulation and testing
Physical Device Connections β
meshtasticd can connect to physical LoRa radios using Portduino β most commonly a radio exposed as a USB serial device, though some boards present the radio over SPI/GPIO (a HAT). Simply omit the -s flag and pass the radio's device node(s) through to the container.
For Serial/USB Meshtastic devices (non-LoRa): Use the Meshtastic Serial Bridge instead
For Bluetooth (BLE) devices: Use the MeshMonitor BLE Bridge instead
Installing meshtasticd β
Docker (Recommended) β
The easiest way to run meshtasticd is via Docker:
docker pull meshtastic/meshtasticd:latestNative Installation β
For native installation on Linux, see the official Meshtastic documentation.
Running meshtasticd β
Configuration File β
meshtasticd requires a config.yaml configuration file. Create one with your desired settings:
# config.yaml
Lora:
Module: sx1262
DIO2_AS_RF_SWITCH: true
CS: 1
IRQ: 2
Busy: 3
Reset: 4
Webserver:
Port: 80
General:
MACAddress: AA:BB:CC:DD:EE:01Basic Usage (Docker) β
Run meshtasticd in simulation mode (no real LoRa hardware):
docker run -d \
--name meshtasticd \
-v ./config.yaml:/etc/meshtasticd/config.yaml:ro \
-p 4403:4403 \
meshtastic/meshtasticd:latest \
meshtasticd -sCommand Line Options β
| Option | Description |
|---|---|
-s | Simulation mode - run without real LoRa hardware |
-c <file> | Specify configuration file path |
-p <port> | TCP port for client connections (default: 4403) |
-d | Enable debug logging |
With Custom TCP Port β
To specify a different TCP port:
docker run -d \
--name meshtasticd \
-v ./config.yaml:/etc/meshtasticd/config.yaml:ro \
-p 4404:4404 \
meshtastic/meshtasticd:latest \
meshtasticd -s -p 4404Configuring MeshMonitor β
Point to localhost β
When using meshtasticd, set the node IP to localhost:
export MESHTASTIC_NODE_IP=localhostOr in your .env file:
MESHTASTIC_NODE_IP=localhostDocker Compose Setup β
When running both meshtasticd and MeshMonitor in Docker, use Docker's bridge networking:
services:
meshtasticd:
image: meshtastic/meshtasticd:latest
container_name: meshtasticd-sim
command: meshtasticd -s
volumes:
- ./config.yaml:/etc/meshtasticd/config.yaml:ro
ports:
- "4403:4403"
restart: unless-stopped
meshmonitor:
image: ghcr.io/yeraze/meshmonitor:latest
container_name: meshmonitor
environment:
- MESHTASTIC_NODE_IP=meshtasticd
- MESHTASTIC_NODE_PORT=4403
ports:
- "8080:3001"
depends_on:
- meshtasticd
restart: unless-stoppedCreate the config.yaml file in the same directory:
# config.yaml
Lora:
Module: sx1262
DIO2_AS_RF_SWITCH: true
CS: 1
IRQ: 2
Busy: 3
Reset: 4
Webserver:
Port: 80
General:
MACAddress: AA:BB:CC:DD:EE:01Then start both services:
docker compose up -dMeshMonitor will be accessible at http://localhost:8080.
Important Notes
- MeshMonitor's internal port is 3001, not 8080. Always map to port 3001.
- Use the Docker service name (
meshtasticd) as the IP address when using bridge networking. - Do not use
network_mode: hostwith port mappings - they are mutually exclusive.
Using a real radio?
The example above runs in simulation mode (the -s flag) and does not talk to attached hardware. To use a physical USB LoRa radio, drop -s and pass the radio's device(s) into the container β see Docker Compose with Physical LoRa Hardware below.
Docker Compose with Physical LoRa Hardware (No Simulation) β
To run meshtasticd with a real USB LoRa radio (e.g., Heltec, RAK, Lilygo):
- Omit the
-sflag from the command - Pass through the USB device to the container
services:
meshtasticd:
image: meshtastic/meshtasticd:latest
container_name: meshtasticd
command: meshtasticd # No -s flag = real hardware mode
volumes:
- ./config.yaml:/etc/meshtasticd/config.yaml:ro
devices:
- /dev/bus/usb:/dev/bus/usb # Pass through USB LoRa radio
ports:
- "4403:4403"
restart: unless-stopped
meshmonitor:
image: ghcr.io/yeraze/meshmonitor:latest
container_name: meshmonitor
environment:
- MESHTASTIC_NODE_IP=meshtasticd
- MESHTASTIC_NODE_PORT=4403
ports:
- "8080:3001"
depends_on:
- meshtasticd
restart: unless-stoppedYou'll also need a config.yaml configured for your specific radio. Set Lora.Module to match your chipset β commonly sx1262, sx1276, sx1280, or llcc68 β along with the correct pin mappings for your board. See the Meshtastic Portduino documentation for per-board pinouts and the full list of supported modules.
Passing through additional devices
/dev/bus/usb covers most USB-attached radios, but depending on your hardware you may need to pass through additional device nodes β for example a specific serial adapter (/dev/ttyUSB0, /dev/ttyACM0), or, for SPI/GPIO HAT radios, /dev/spidev* and /dev/gpiochip*. List your devices before and after plugging in the radio to see which nodes appear, then add each one under the service's devices: list:
lsusb
ls /dev/ttyUSB* /dev/ttyACM* /dev/spidev* /dev/gpiochip* 2>/dev/nullUSB Permissions
If the container can't access the USB device, ensure your user has permissions:
# Check device is detected
lsusb
# Add your user to the dialout group (log out and back in)
sudo usermod -a -G dialout $USERCredit
The physical-hardware configuration above was contributed by @Saucesquatch (corvock). Thanks!
Using Docker Host Network β
If you prefer host networking (no port isolation):
services:
meshtasticd:
image: meshtastic/meshtasticd:latest
command: meshtasticd -s
volumes:
- ./config.yaml:/etc/meshtasticd/config.yaml:ro
network_mode: host
restart: unless-stopped
meshmonitor:
image: ghcr.io/yeraze/meshmonitor:latest
network_mode: host
environment:
- MESHTASTIC_NODE_IP=localhost
- MESHTASTIC_NODE_PORT=4403
restart: unless-stoppedWith host networking, MeshMonitor will be accessible at http://localhost:3001.
Initial Configuration β
After starting meshtasticd, you can configure it using the Meshtastic CLI:
# Connect to the virtual node
meshtastic --host localhost
# Set your node name
meshtastic --set-owner "My Virtual Node"
# Configure LoRa region
meshtastic --set lora.region USTesting the Connection β
Verify MeshMonitor can connect to your meshtasticd instance:
Start both containers:
bashdocker compose up -dCheck meshtasticd logs:
bashdocker logs meshtasticd-simYou should see router and packet processing messages.
Check MeshMonitor logs:
bashdocker logs meshmonitorLook for
Connection status: connectedmessage.Access MeshMonitor at
http://localhost:8080
Expected Behavior β
When running with meshtasticd in simulation mode:
- MeshMonitor will connect and show the simulated node
- You'll see telemetry updates (battery, uptime, etc.)
- Some admin queries may return
NO_RESPONSE- this is normal for simulated nodes - The node will appear with a name like "Meshtastic c43b"
Troubleshooting β
Port Already in Use β
If you see "Address already in use" errors:
# Find what's using port 4403
lsof -i :4403
# Use a different port
docker run ... meshtasticd -s -p 4404Connection Refused β
If MeshMonitor cannot connect:
Verify
meshtasticdis running:bashdocker ps | grep meshtasticdCheck meshtasticd logs for errors:
bashdocker logs meshtasticd-simVerify port is accessible:
bashnc -zv localhost 4403
NO_RESPONSE Warnings β
MeshMonitor may show NO_RESPONSE warnings for LocalStats requests. This is expected behavior - the simulated node doesn't implement all admin features.
Docker Networking Issues β
Common mistakes:
- Using
network_mode: hostwith port mappings (they're mutually exclusive) - Using
localhostas IP when containers are on bridge network (use service name instead) - Mapping to wrong internal port (MeshMonitor uses 3001, not 8080)
Production Use β
Using systemd β
For native installations, create a systemd service file /etc/systemd/system/meshtasticd.service:
[Unit]
Description=Meshtastic Daemon
After=network.target
[Service]
Type=simple
User=meshtastic
ExecStart=/usr/bin/meshtasticd -c /etc/meshtasticd/config.yaml
Restart=always
RestartSec=10
[Install]
WantedBy=multi-user.targetEnable and start the service:
sudo systemctl enable meshtasticd
sudo systemctl start meshtasticdUsing Docker β
Run meshtasticd as a Docker container:
docker run -d \
--name meshtasticd \
--restart unless-stopped \
-v ./config.yaml:/etc/meshtasticd/config.yaml:ro \
-p 4403:4403 \
meshtastic/meshtasticd:latest \
meshtasticd -sNext Steps β
- Connect Serial/USB devices with the Serial Bridge
- Connect Bluetooth devices with the BLE Bridge
- Configure SSO for authentication
- Set up a reverse proxy for external access
- Deploy to production with proper monitoring