# Zigbee2MQTT + Mosquitto on naruto — Design Spec **Date:** 2026-06-03 ## Goal Run Zigbee2MQTT and Mosquitto as Docker containers on naruto, managed by the `raspberry_pi` Ansible role. Home Assistant (running in k3s) connects to Mosquitto over the LAN. ## Hardware - Host: naruto (Pi 4, 192.168.20.13) - Zigbee coordinator: SONOFF Dongle Lite MG21 on `/dev/ttyUSB0` - Stable by-id path: `/dev/serial/by-id/usb-SONOFF_SONOFF_Dongle_Lite_MG21_0263f93f46a2ef11b078926661ce3355-if00-port0` ## Architecture Two containers via Docker Compose on naruto. Ansible templates all configs and manages the stack. Home Assistant adds the MQTT integration pointing at `192.168.20.13:1883`. ``` [SONOFF Dongle /dev/ttyUSB0] | [zigbee2mqtt container] | MQTT (internal docker network) [mosquitto container] :1883 | [Home Assistant in k3s] — via LAN 192.168.20.13:1883 ``` ## Directory Layout on naruto ``` /opt/docker/ config/ mosquitto/ mosquitto.conf data/ log/ zigbee2mqtt/ configuration.yaml data/ compose/ docker-compose.yml ``` ## Mosquitto Config - Listens on port 1883 - No authentication (internal LAN only) - Persistence enabled, logs to `/opt/docker/config/mosquitto/log/` ## Zigbee2MQTT Config - Serial port: `/dev/serial/by-id/usb-SONOFF_SONOFF_Dongle_Lite_MG21_0263f93f46a2ef11b078926661ce3355-if00-port0` - MQTT broker: `mqtt://mosquitto:1883` (internal docker network) - Network key: stored in `vars/group_vars/raspberry_pi/secrets.yaml` as `vault_raspberry_pi.zigbee2mqtt.network_key` - Frontend enabled on port 8080 for local device management ## Secrets `vars/group_vars/raspberry_pi/secrets.yaml` (vault-encrypted, placeholder for now): ```yaml vault_raspberry_pi: zigbee2mqtt: network_key: "YOUR_ZIGBEE_NETWORK_KEY" ``` ## Ansible Changes | Action | Path | Responsibility | |--------|------|----------------| | Modify | `roles/raspberry_pi/tasks/main.yaml` | Include numbered task files | | Create | `roles/raspberry_pi/tasks/10_directories.yaml` | Create `/opt/docker/` tree | | Create | `roles/raspberry_pi/tasks/20_zigbee2mqtt.yaml` | Template configs, start compose | | Create | `roles/raspberry_pi/templates/zigbee2mqtt/docker-compose.yml.j2` | Compose file | | Create | `roles/raspberry_pi/templates/zigbee2mqtt/mosquitto.conf.j2` | Mosquitto config | | Create | `roles/raspberry_pi/templates/zigbee2mqtt/z2m-configuration.yaml.j2` | Zigbee2MQTT config | | Create | `vars/group_vars/raspberry_pi/secrets.yaml` | Network key placeholder | ## Host Constraint The `raspberry_pi` role applies to both naruto and pi. The Zigbee2MQTT tasks must be guarded with `when: inventory_hostname == 'naruto'` since the USB dongle is only on naruto.