I’m a docker user and have my instances running on a swarm behind traefik. What that means is that I really don’t know / don’t care what machine is running my container at any given time - it just works. I have a few random mini-pc style linux hosts, and some misc arm devices. Since the HA docker image is multi-arch, the container spins up on whichever host and traefik finds it by magic.
This is all great, but a bit of a problem arises when it comes to mapping hardware devices to the container. I wanted to attach a google Coral, and of course a Zigbee and Zwave dongle so I can get rid of my external hub.
The issue is that Docker doesn’t support devices in Swarm mode. There are some hacks, but, ymmv. Another way is to add a node specifically for USB devices. So this is the path I took.
I manage my nodes using Portainer. So I used their edge agent to connect up a RockPro64 node, instead of adding it to the swarm. That works great - since now it’s managed in the same portainer instance i’m already using.
In the new node I deploy this stack to link up my usb radios
version: '3.7'
services:
## ZWAVEJS
## CONNECTS TO THE USB ZWAVE RADIO
## SETS UP A WEBSOCKET SERVER PORT 3000
## HOME-ASSISTANT CAN CONNECT AND AUTO-DISCOVER ENTITIES
## WEB INTERFACE ON PORT 8091
zwavejs2mqtt:
container_name: zwavejs2mqtt
image: zwavejs/zwavejs2mqtt:latest
restart: unless-stopped
tty: true
stop_signal: SIGINT
environment:
- SESSION_SECRET=**********
- TZ=America/**********
networks:
- zwave
devices:
- '/dev/serial/by-id/usb-0658_0200-if00:/dev/serial/by-id/usb-0658_0200-if00'
volumes:
- zwave-data:/usr/src/app/store
ports:
- '8091:8091' # port for web interface
- '3000:3000' # port for zwave-js websocket server
- '9001:9001' # port for prometheus metrics scraper
## ZIGBEE-2-MQTT
## CONNECTS TO THE USB ZIGBEE RADIO
## PUBLISHES TO MQTT SERVER
## HOME-ASSISTANT CAN CONNECT AND AUTO-DISCOVER ENTITIES
zigbee2mqtt:
container_name: zigbee2mqtt
image: koenkk/zigbee2mqtt
volumes:
- zigbee-data:/app/data
- /run/udev:/run/udev:ro
devices:
- /dev/ttyACM0:/dev/ttyACM0
restart: unless-stopped
networks:
- zigbee
environment:
- TZ=America/********
## ZIGBEE2MQTT WEBUI
zigbee2mqttAssistant:
image: carldebilly/zigbee2mqttassistant
networks:
- zigbee
environment:
- Z2MA_SETTINGS__MQTTSERVER=mqtt.**********.com
- Z2MA_SETTINGS__MQTTUSERNAME=**********
- Z2MA_SETTINGS__MQTTPASSWORD=**********
- TZ=America/**********
ports:
- '8880:80'
restart: unless-stopped
volumes:
zigbee-data:
driver: local
name: zigbee-data
driver_opts:
type: none
o: bind
device: /mnt/dockerdata/zigbee2mqtt/data
volumes:
zwave-data:
driver: local
name: zwave-data
driver_opts:
type: none
o: bind
device: /mnt/dockerdata/zwavedata/data
networks:
zwave:
zigbee:
I don’t use traefik for this node because I have no need to remotely access these services. The results are great, I was able to ditch my hub after a couple hours of exlusion / inclusion! Really easy now to extend range, I can just drop one of these SBC’s wherever, attach a couple of Radios, and off it goes.
The volume binds into /mnt are there because I keep all my docker volumes on a central storage server, which is mounted @ /mnt/dockerdata/. You can use this method to put the volumes into any local dir, whether it’s mounted or not.