This runbook covers deploying meshtasticd SIM (virtual) nodes inside LXC containers on Proxmox, each paired with a dedicated service (BBS, MeshSense, etc.). SIM nodes communicate with your real radio node over UDP and appear as normal nodes on the mesh — clients, maps, and other [[services]] can't tell the difference.
**Design principle:** One container = one SIM daemon + one service. Clean isolation, easy to snapshot, migrate, or tear down without affecting anything else.
UDP is what connects SIM nodes to the rest of your mesh. Every meshtasticd instance — real radio and all SIM nodes — needs UDP enabled and must be able to reach each other on the network.
Add to your SIM node's config:
```yaml
Networking:
EnableUDP: true
```
**Also ensure your real radio node has UDP enabled** in its own config.
### Network Considerations
For UDP mesh traffic to flow between LXC containers and your real radio node:
- All containers and the real radio host must be on the **same Layer 2 network** (same bridge, same subnet) — UDP broadcast/multicast needs to reach all instances.
- If your real radio runs on a different host (e.g., a Raspberry Pi), make sure it's on the same VLAN/subnet as the LXC bridge.
- Proxmox's default `vmbr0` bridge works fine if everything is on the same network.
- If you're running the real radio in its own LXC and passing through USB, the same bridge rules apply.
**Firewall note:** If you have Proxmox firewall or iptables rules on the host, ensure UDP traffic between containers is not blocked. Meshtasticd uses UDP broadcast by default — verify your bridge allows broadcast forwarding.
---
## Step 5: Configure the systemd Service
The meshtasticd package likely installs a default unit file. If you need to customize it:
```bash
sudo systemctl edit meshtasticd --full
```
Or create/verify `/etc/systemd/system/meshtasticd.service`:
**Note:** The TUN device must already be configured in the container config (done in Step 1). If Tailscale fails to start, verify `/dev/net/tun` exists inside the container.
---
## Step 6: Configure the SIM Node
With the daemon running and no service connected yet, configure it via CLI:
If you don't set a position, the node still functions on the mesh but won't appear on maps.
---
## Step 7: Install and Connect Your Service
Now install whichever service this container is dedicated to and point it at `localhost:4403` (or whatever the default meshtasticd API port is).
### Example: BBS
```bash
# Install your BBS software of choice
# Point it at the local meshtasticd instance
# BBS_CONFIG: host=localhost, port=4403
```
### Example: MeshSense
```bash
# MeshSense supports non-default ports
# Configure it to connect to localhost:4403
```
**Reminder:** One client API connection per daemon. Once the service is connected, don't also try to connect a client app to the same instance. If you need to reconfigure the node, stop the service first.
---
## Provisioning Additional Containers
For each new service, repeat steps 1–7 with:
1. A new container ID and hostname (e.g., `mesh-sense`, `mesh-bot`)
2. A **unique MAC address** in config.yaml
3. The specific service installed alongside meshtasticd
### Quick Clone Approach
Once you have one container fully set up, you can clone it in Proxmox and just change:
- Container hostname
- MAC address in `/etc/meshtasticd/config.yaml`
- The service installed/configured
- Node owner name via `meshtastic --host localhost --set-owner "NewName"`
Adjust the device path and cgroup major number as needed for your hardware. The container will also need a `config.yaml` with the real LoRa module config instead of `Module: sim`.
---
## Troubleshooting
### SIM nodes not seeing the real radio (or each other)
- Verify UDP is enabled on **all** instances
- Confirm all containers are on the same bridge/subnet
- Check for firewall rules blocking UDP broadcast between containers
- Test basic connectivity: `ping` between containers
### Node ID collisions / "things get weird"
- Every SIM node must have a **unique MAC address** — check each container's config.yaml
- After changing a MAC, restart meshtasticd and verify with `meshtastic --host localhost --info`
### Service can't connect to meshtasticd
- Is meshtasticd actually running? `systemctl status meshtasticd`
- Is another client already connected? Only one API connection per instance.
- Check the port: `ss -tlnp | grep 4403`
### Config not taking effect
- Make sure `ConfigDirectory` is commented out or pointed somewhere empty so default config.d files don't override your settings
- Restart after config changes: `systemctl restart meshtasticd`
### Permission errors
- VFS and config directories must be owned by the `meshtasticd` user
Procedure sourced from a community discussion between pdxlocs, tedward, and wehooper4 regarding multi-daemon meshtasticd deployments with SIM mode. Adapted for LXC/Proxmox deployment.