Skip to content

Smart Home: Connecting Zigbee Devices to Home Assistant Container via Docker

Building a local, cloud-independent smart home is one of the most rewarding projects you can build on a Raspberry Pi. While Wi-Fi smart plugs and sensors are easy to buy, they saturate your router and often depend on external cloud servers (e.g. Tuya, SmartLife).

The Zigbee protocol is the gold standard for smart home sensor networks. Zigbee devices form a low-power, self-healing mesh network, and require no internet access to operate.

This guide walks you through: 1. Setting up a USB Zigbee Coordinator (e.g., Sonoff Zigbee 3.0 USB Dongle Plus). 2. Deploying a containerized stack containing Home Assistant Container, Zigbee2MQTT, and the Mosquitto MQTT Broker using Docker Compose. 3. Pairing a Zigbee sensor and integrating it locally with Home Assistant.


Architecture Overview

graph LR A["Zigbee Sensors (Temp, Motion, Switch)"] -->|Wireless Mesh| B["USB Zigbee Dongle (Pi)"] B -->|Serial Interface| C["Zigbee2MQTT (Container)"] C -->|Publish/Subscribe| D["Mosquitto MQTT Broker (Container)"] D -->|MQTT Auto-Discovery| E["Home Assistant (Container)"] style C fill:#f72585,stroke:#b5179e,color:#fff style D fill:#7209b7,stroke:#560bad,color:#fff style E fill:#4cc9f0,stroke:#4361ee,color:#000

Step 1: Identify and Prepare the USB Zigbee Dongle

Insert your USB Zigbee dongle into one of the blue USB 3.0 ports of your Raspberry Pi. If you are using a Raspberry Pi 4 or 5, it is highly recommended to use a USB 2.0 extension cable (1 meter) to connect the dongle. The USB 3.0 ports and internal circuitry generate high-frequency radio interference that drastically reduces Zigbee range and causes pairing drops.

Find the serial device path of your dongle:

ls -la /dev/serial/by-id/
(You will see a link pointing to a port like /dev/ttyUSB0 or /dev/ttyACM0. Note the full /dev/serial/by-id/usb-ITead_Sonoff_Zigbee_3.0_USB_Dongle_Plus_... path; it is much safer to use in Docker than /dev/ttyUSB0, as it won't change if you plug in other USB devices).

Step 2: Configure Workspace and Zigbee2MQTT Settings

Create a dedicated directory structure for the Docker stack configuration files:

mkdir -p ~/smart-home/{mosquitto/config,zigbee2mqtt/data,homeassistant}
cd ~/smart-home

1. Configure Mosquitto MQTT Broker

Create a configuration file for the broker to allow communication between containers:

nano mosquitto/config/mosquitto.conf
Add the following basic configuration:
1
2
3
4
5
6
7
persistence true
persistence_location /mosquitto/data/
log_dest file /mosquitto/log/mosquitto.log

# Allow anonymous local connections inside the docker network
listener 1883 0.0.0.0
allow_anonymous true

2. Configure Zigbee2MQTT

Create a configuration file defining the serial adapter path and MQTT broker connection details:

nano zigbee2mqtt/data/configuration.yaml
Add the following configuration (replace <YOUR_SERIAL_PORT_BY_ID> with the exact path you found in Step 1):
1
2
3
4
5
6
7
8
9
homeassistant: true # Enable automatic integration with Home Assistant
permit_join: false # Disable joining by default for security
mqtt:
  base_topic: zigbee2mqtt
  server: 'mqtt://mosquitto:1883'
serial:
  port: <YOUR_SERIAL_PORT_BY_ID>
frontend:
  port: 8080 # Web UI for pairing and managing devices

Step 3: Write the Docker Compose Stack

This Docker Compose file binds the MQTT broker, Zigbee2MQTT, and Home Assistant together, sharing a common virtual bridge network.

Create the file:

nano docker-compose.yml

Add the following stack configuration:

version: '3.8'

services:
  # MQTT Broker: Message passage hub
  mosquitto:
    image: eclipse-mosquitto:latest
    container_name: mosquitto
    ports:
      - "1883:1883"
    volumes:
      - ./mosquitto/config:/mosquitto/config
      - mosquitto_data:/mosquitto/data
      - mosquitto_log:/mosquitto/log
    restart: unless-stopped

  # Zigbee2MQTT: Translates Zigbee signals to MQTT messages
  zigbee2mqtt:
    image: koenkk/zigbee2mqtt:latest
    container_name: zigbee2mqtt
    depends_on:
      - mosquitto
    ports:
      - "8080:8080"
    volumes:
      - ./zigbee2mqtt/data:/app/data
      - /run/udev:/run/udev:ro
    devices:
      - "/dev/serial/by-id/usb-ITead_Sonoff_Zigbee_3.0_USB_Dongle_Plus_xxxx:/dev/ttyUSB0" # Map host dongle to container
    restart: unless-stopped

  # Home Assistant: Core automation engine
  homeassistant:
    image: ghcr.io/home-assistant/home-assistant:stable
    container_name: homeassistant
    depends_on:
      - mosquitto
    volumes:
      - ./homeassistant:/config
      - /etc/localtime:/etc/localtime:ro
    ports:
      - "8123:8123"
    restart: unless-stopped

volumes:
  mosquitto_data:
  mosquitto_log:
Note: Make sure the devices: section under zigbee2mqtt maps your exact physical serial ID path to /dev/ttyUSB0 inside the container.

Step 4: Deploy and Pair Your First Device

Start the stack in the background:

docker compose up -d

1. Enable Pairing Mode in Zigbee2MQTT

  1. Open your browser and navigate to http://<your-pi-ip>:8080 to access the Zigbee2MQTT Dashboard.
  2. Click Permit join (All) at the top right of the navigation bar. A countdown timer will begin.
  3. Grab your Zigbee sensor (e.g. Xiaomi, Sonoff, or Tuya Temperature sensor).
  4. Press and hold the reset/pairing button on the sensor for 5 seconds until the LED starts flashing.
  5. In the Zigbee2MQTT Web UI, you will see a notification: Device '0x00158d000...' joined. You can rename this device (e.g., Living Room Temp) directly in the dashboard.

Step 5: Integrating with Home Assistant

Now, let's connect Home Assistant to our MQTT broker so it can automatically discover the paired Zigbee devices.

  1. Navigate to http://<your-pi-ip>:8123 to open Home Assistant.
  2. Go through the initial setup (create account, set location).
  3. Navigate to Settings -> Devices & Services.
  4. Click Add Integration in the bottom right corner, search for MQTT, and select it.
  5. Set the Broker configuration:
    • Broker: mosquitto (We use the Docker service container name as the hostname)
    • Port: 1883
    • Leave username/password blank (as configured in mosquitto.conf).
  6. Click Submit.

Home Assistant will automatically query the MQTT broker. Because homeassistant: true is configured in zigbee2mqtt, your newly paired Zigbee sensor will instantly appear as a device in Home Assistant with all its entities (temperature, humidity, battery percentage) fully exposed!


Troubleshooting & Maintenance

Permission Denied on Serial Port

If the zigbee2mqtt container logs show a serial connection error, the container may lack host permissions. You can fix this by adding the dialout group permissions on the host:

1
2
3
sudo usermod -aG dialout $USER
# restart docker service to apply permissions
sudo systemctl restart docker

By leveraging this containerized stack, you have created a completely local, lightning-fast, and highly secure smart home engine on your Raspberry Pi.