Найти в Дзене
Sprut.ai

Установка Home Assistant + mosquitto + zigbee2mqtt в Docker

Оглавление

Вводная

Ранее не писал статьи, делал только для себя гайды/шпаргалки, что бы не забыть. Так что это мой первый опыт. Предупреждаю сразу, внизу будет много Shell команд, настроек и т.п.

Для чего это все нужно? Хотя бы для того, что стоит один раз все настроить и в дальнейшем разворачивать все сервисы парой команд за несколько минут на любом устройстве. Это уже многого стоит - нашего времени! =)

Docker и docker-compose

Обновляем индексы репозиториев и устанавливаем все доступные обновления:

sudo apt-get update
sudo apt-get upgrade -ySHELLКОПИРОВАТЬ

Устанавливаем нужные Docker пакеты:

sudo apt-get install -y apt-transport-https ca-certificates curl gnupg2 software-properties-common SHELLКОПИРОВАТЬ

Добавляем официальный ключ GPG Docker:

curl -fsSL https://download.docker.com/linux/debian/gpg | sudo apt-key add -SHELLКОПИРОВАТЬ

Добавляем официальный репозиторий Docker (в моем случае raspberry pi, это armhf):armhf:

echo "deb [arch=armhf] https://download.docker.com/linux/debian $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.listSHELLКОПИРОВАТЬ

x86_64/amd64:

sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/debian $(lsb_release -cs) stable"SHELLКОПИРОВАТЬ

arm64:

echo "deb [arch=arm64] https://download.docker.com/linux/debian $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.listSHELLКОПИРОВАТЬ

Обновим индексы репозиториев и установим Docker:

sudo apt-get update
sudo apt-get install -y docker-ceSHELLКОПИРОВАТЬ

Далее установим python3, пакетный менеджер pip, обновим pip и установим docker-compose:

sudo apt-get install -y python3 python3-pip
sudo pip3 install --upgrade pip
sudo pip3 install docker-composeSHELLКОПИРОВАТЬ

Так же вы можете посмотреть подробную инструкцию по установке docker, для вашего устройства и архитектуры на официальной странице документации Docker на сайте https://docs.docker.com/install/.

Установка Portainer

Для удобства использования и управления контейнерами Docker, я рекомендую использовать веб-морду portainer

Что бы установить Portainer, выполним следующую команду в консоли:

sudo docker run --restart always --name portainer -d -p 9000:9000 -v /var/run/docker.sock:/var/run/docker.sock -v portainer_data:/data portainer/portainer:1.19.2SHELLКОПИРОВАТЬ

Открываем в браузере http://YOU_IP:9000/ и попадаем в нашу установленную админку Portainer

Вводим логин и пароль, и создаем пользователя.
Вводим логин и пароль, и создаем пользователя.
Далее указываем, что Docker у нас установлен локально, и жмем кнопку connect
Далее указываем, что Docker у нас установлен локально, и жмем кнопку connect
-3

Portainer. Развертывание при помощи docker-compose

В дальнейшем все действия будем выполнять от нашего пользователя pi (1000:1000), вашем случае может быть другой. Добавим нашего пользователя в группу docker, и авторизовываемся заново:

sudo usermod -a -G docker pi && su piSHELLКОПИРОВАТЬ

Создадим папку /home/pi/smarthome и в нем файл docker-compose.yml и папку portainer для данных сервиса Portainer:

mkdir /home/pi/smarthome
touch /home/pi/smarthome/docker-compose.ymlSHELLКОПИРОВАТЬ

Добавим в файл docker-compose.yml следующее:

version: '3.3'

services:

portainer:
container_name: portainer
image: portainer/portainer:1.19.2
restart: always
ports:
- 9000:9000
volumes:
- ./portainer:/data
- /var/run/docker.sock:/var/run/docker.sockYAMLКОПИРОВАТЬ

Останавливаем и удаляем контейнер portainer, далее перенесем его данные в созданную папку /home/pi/smarthome/portainer и меняем владельца с root на нашего пользователя:

docker stop portainer
docker rm portainer
sudo mv /var/lib/docker/volumes/portainer_data/_data /home/pi/smarthome/
sudo chown -R pi:pi /home/pi/smarthome/
mv /home/pi/smarthome/_data /home/pi/smarthome/portainer
docker volume rm portainer_dataSHELLКОПИРОВАТЬ

Поднимаем контейнер portainer и запускаем его в фоне при помощи docker-compose:

cd /home/pi/smarthome/
docker-compose up -dSHELLКОПИРОВАТЬ

Mosquitto

Создадим необходимые для работы брокера папки и файлы:

mkdir /home/pi/smarthome/mosquitto
mkdir /home/pi/smarthome/mosquitto/config
mkdir /home/pi/smarthome/mosquitto/data
mkdir /home/pi/smarthome/mosquitto/log
touch /home/pi/smarthome/mosquitto/config/mosquitto.conf
touch /home/pi/smarthome/mosquitto/config/passwdSHELLКОПИРОВАТЬ

Добавляем сервис Mosquitto в docker-compose.yml в конец файла:

eclipse-mosquitto:
container_name: mosquitto
image: eclipse-mosquitto:latest
restart: always
volumes:
- ./mosquitto/config:/mosquitto/config
- ./mosquitto/data:/mosquitto/data
- ./mosquitto/log:/mosquitto/log
ports:
- 1883:1883
user: '1000:1000'YAMLКОПИРОВАТЬ

Создаем контейнер:

cd /home/pi/smarthome/
docker-compose up -dSHELLКОПИРОВАТЬ

Создаем mqtt пользователя:

docker exec -it mosquitto mosquitto_passwd -c /mosquitto/config/passwd userSHELLКОПИРОВАТЬ

вводим пароль и подтверждаем егоФайл конфигурации /home/pi/smarthome/mosquitto/config/mosquitto.conf:
вводим пароль и подтверждаем егоФайл конфигурации /home/pi/smarthome/mosquitto/config/mosquitto.conf:

persistence true
persistence_location /mosquitto/data
allow_anonymous false
log_dest file /mosquitto/log/mosquitto.log
password_file /mosquitto/config/passwdSHELLКОПИРОВАТЬ

Перезапустим наш сервис mosquitto:

docker restart mosquittoSHELLКОПИРОВАТЬ

На этом этапе mosquitto установлен и настроен.

zigbee2mqtt

Создадим папку для работы нашего zigbee2mqtt моста:

mkdir /home/pi/smarthome/zigbee2mqttSHELLКОПИРОВАТЬ

Добавляем сервис zigbee2mqtt в docker-compose.yml в конец файла:

zigbee2mqtt:
container_name: zigbee2mqtt
image: koenkk/zigbee2mqtt:arm32v6 # arm32 (raspberry pi)
#image: koenkk/zigbee2mqtt:latest # x86_64/amd64
restart: always
volumes:
- ./zigbee2mqtt:/app/data
devices:
- /dev/serial/by-id/usb-Texas_Instruments_TI_CC2531_USB_CDC___0X00124B0014D9E292-if00:/dev/ttyACM0
user: '1000:20'SHELLКОПИРОВАТЬ

Заметьте что id пользователя 1000, а id группы 20, это нужно, для того что бы пользователь в контейнере смог использовать группу dialout.

Нам нужно прокинуть наш usb-стик из хоста в контейнер, в моем случае это: 

/dev/serial/by-id/usb-Texas_Instruments_TI_CC2531_USB_CDC___0X00124B0014D9E292-if00

Где он находиться у вас, узнать можно выполнив команду в консоли:

ls /dev/ttyACM*SHELLКОПИРОВАТЬ

У меня несколько устройств в системе, и что бы не заблудиться в них, я указал по уникальному идентификатору устройства:
У меня несколько устройств в системе, и что бы не заблудиться в них, я указал по уникальному идентификатору устройства:

ls /dev/serial/by-id/usb-*SHELLКОПИРОВАТЬ

А так же для использования usb-стика нашим пользователем pi, нужно его добавить в группу dialout. Выполним команду в консоле:
А так же для использования usb-стика нашим пользователем pi, нужно его добавить в группу dialout. Выполним команду в консоле:

sudo usermod -a -G dialout piSHELLКОПИРОВАТЬ

Запускаем контейнер c zigbee2mqtt:

cd /home/pi/smarthome/
docker-compose up -dSHELLКОПИРОВАТЬ

Сервис запущен, нужно только настроить подключение к ранее подготовленному mosquitto.
Сервис запущен, нужно только настроить подключение к ранее подготовленному mosquitto.

После развертывания нашего контейнера, в папке /home/pi/smarthome/zigbee2mqtt будут находиться конфигурационные файлы zigbee2mqtt.

ls -lia /home/pi/smarthome/zigbee2mqttSHELLКОПИРОВАТЬ

Настроим файл конфигураций /home/pi/smarthome/zigbee2mqtt/configuration.yaml, добавим в него настройки подключение к mqtt брокеру:
Настроим файл конфигураций /home/pi/smarthome/zigbee2mqtt/configuration.yaml, добавим в него настройки подключение к mqtt брокеру:

# Home Assistant integration (MQTT discovery)
homeassistant: true

# allow new devices to join
permit_join: true

# MQTT settings
mqtt:
# MQTT base topic for zigbee2mqtt MQTT messages
base_topic: zigbee2mqtt
# MQTT server URL
server: 'mqtt://192.168.2.163'
# MQTT server authentication, uncomment if required:
user: user
password: qwerty

# Serial settings
serial:
# Location of CC2531 USB sniffer
port: /dev/ttyACM0
YAMLКОПИРОВАТЬ

Заметьте, я указал IP-адрес хоста 192.168.2.163, то есть IP-адрес малины в нашей локальной сети.

Перезапустим контейнер zigbee2mqtt:

docker restart zigbee2mqttSHELLКОПИРОВАТЬ

Как вы можете заметить, все завелось, zigbee2mqtt успешно подключился к mqtt брокеру.
Как вы можете заметить, все завелось, zigbee2mqtt успешно подключился к mqtt брокеру.

Home Assistant - вариант №1 ("легко")

Официальный образ Home Assistant. Плюс данного способа в том, что все очень просто разворачивает. Выполнил команду, и все скачалось и запустилось. Минус в том, что данный образ жирноват и кушает много места на диске, целых 1ГБ на образе для arm32 и 2.2ГБ для x86_64/amd64!

Найти образ (image) Home Assistant именно для вашего устройства и архитектуры, можно на официальной странице https://hub.docker.com/u/homeassistant.

И так приступим, добавим в наш docker-compose.yml следующие строки для нашего контейнера:

homeassistant:
container_name: homeassistant
image: homeassistant/raspberrypi3-homeassistant # arm32
#image: homeassistant/home-assistant # x86_64/amd64
volumes:
- ./homeassistant/config:/config
- /etc/localtime:/etc/localtime:ro
restart: always
network_mode: host
user: '1000:1000'YAMLКОПИРОВАТЬ

Создадим папку, где будут находиться конфигурационные файлы HA:

mkdir /home/pi/smarthome/homeassistant
mkdir /home/pi/smarthome/homeassistant/configSHELLКОПИРОВАТЬ

Соберем контейнер:

cd /home/pi/smarthome/
docker-compose up -dSHELLКОПИРОВАТЬ

Готово, создаем учетную запись и добавляем в конфигурационный файл /home/pi/smarthome/homeassistant/config/configuration.yamlнастройки подключения mqtt брокера:
Готово, создаем учетную запись и добавляем в конфигурационный файл /home/pi/smarthome/homeassistant/config/configuration.yamlнастройки подключения mqtt брокера:

#https://www.home-assistant.io/components/mqtt/
mqtt:
broker: 192.168.2.163
port: 1883
username: user
password: qwerty
client_id: homeassistant
birth_message:
topic: 'hass/status'
payload: 'online'
qos: 1
retain: true
will_message:
topic: 'hass/status'
payload: 'offline'
qos: 1
retain: trueYAMLКОПИРОВАТЬ

 И перезапускаем Home Assistant.
 И перезапускаем Home Assistant.

Home Assistant - вариант №2 (оптимизация)

Суть всей оптимизации в том, что мы будем устанавливать только необходимые компоненты которые будем использовать в нашем Home Assistant. Во втором варианте мы будем собирать наш контейнер на основе образа alpine (5MB), фильтровать зависимости Home Assistant, их весьма много, да же я бы сказал очень много. Тем самым размер нашего образа весьма похудеет.

И так приступим, создадим файл Dockerfile, в котором будем описывать сборку нашего образа:

touch /home/pi/smarthome/homeassistant/DockerfileSHELLКОПИРОВАТЬ

Содержимое /home/pi/smarthome/homeassistant/Dockerfile:

FROM alpine:3.8
LABEL maintainer="tweaker3 <tweaker3@ya.ru>"
LABEL Description="Home Assistant"

# Часовой пояс
ARG TIMEZONE=Europe/Moscow
# ID пользваотеля на хост машине, узнать в консоле: echo $(id -u)
ARG UID=1000
# ID группы пользователя на хост машине, узнать в консоле: echo $(id -g)
ARG GID=1000
# Версия Home Assistant (что бы обновить, нужно менять)
ARG VERSION=0.83.3
# Список python пакетов/зависимостей ХА, которые нам необходимы
ARG PLUGINS="frontend|sqlalchemy|xmltodict|netdisco|distro|aiohttp_cors|paho-mqtt"

ADD "https://raw.githubusercontent.com/home-assistant/home-assistant/${VERSION}/requirements_all.txt" /tmp

RUN apk add --no-cache python3 libffi-dev libressl-dev eudev-dev libstdc++ && \
addgroup -g ${GID} hass && \
adduser -h /config -D -G hass -s /bin/sh -u ${UID} hass && \
addgroup hass dialout && \
pip3 install --upgrade --no-cache-dir pip && \
apk add --no-cache --virtual=build-dependencies build-base linux-headers python3-dev tzdata && \
cp "/usr/share/zoneinfo/${TIMEZONE}" /etc/localtime && echo "${TIMEZONE}" > /etc/timezone && \
sed '/^$/q' /tmp/requirements_all.txt > /tmp/requirements_core.txt && \
sed '1,/^$/d' /tmp/requirements_all.txt > /tmp/requirements_plugins.txt && \
egrep -e "${PLUGINS}" /tmp/requirements_plugins.txt | grep -v '#' > /tmp/requirements_plugins_filtered.txt && \
pip3 install --no-cache-dir -r /tmp/requirements_core.txt && \
pip3 install --no-cache-dir -r /tmp/requirements_plugins_filtered.txt && \
pip3 install --no-cache-dir homeassistant=="${VERSION}" && \
# For telegram
pip3 install --no-cache-dir netifaces PySocks && \
apk del build-dependencies && \
rm -rf /tmp/* /var/tmp/* /var/cache/apk/*

USER hass
ENTRYPOINT ["hass", "--open-ui", "--config=/config"]SHELLКОПИРОВАТЬ

Поправим наш сервис homeassistant в файле docker-compose.yml:

homeassistant:
container_name: homeassistant
build: ./homeassistant
#image: homeassistant/raspberrypi3-homeassistant # arm32
#image: homeassistant/home-assistant # x86_64/amd64
volumes:
- ./homeassistant/config:/config
- /etc/localtime:/etc/localtime:ro
restart: always
network_mode: host
YAMLКОПИРОВАТЬ

Удаляем прошлый контейнер и образ, и собираем новый:

cd /home/pi/smarthome/
docker stop homeassistant
docker rm homeassistant
docker rmi homeassistant/raspberrypi3-homeassistant:latest
docker-compose build
docker-compose up -dSHELLКОПИРОВАТЬ

Ждем завершение сборки.

Как нам узнать какой пакет нужно устанавливать? Очень просто, например я использую трекинг по nmap. 

Добавляем конфигурации в Home Assistant, перезагружаем его, и идем смотреть логи:

device_tracker:
- platform: nmap_tracker
hosts: 192.168.2.190
home_interval: 10
YAMLКОПИРОВАТЬ

В логи сыплются ошибки что не найден nmap, открываем ссылку https://raw.githubusercontent.com/home-assistant/home-assistant/0.83.3/requirements_all.txt и ищем там пакет отвечающий за работу nmap:
В логи сыплются ошибки что не найден nmap, открываем ссылку https://raw.githubusercontent.com/home-assistant/home-assistant/0.83.3/requirements_all.txt и ищем там пакет отвечающий за работу nmap:

# homeassistant.components.device_tracker.nmap_tracker
python-nmap==0.6.1SHELLКОПИРОВАТЬ

Добавляем имя пакета в наш Dockerfile, а так же укажем nmap в список устанавливаемого софта для образа alpine:

ARG PLUGINS="frontend|sqlalchemy|xmltodict|netdisco|distro|aiohttp_cors|paho-mqtt|python-nmap"

SHELLКОПИРОВАТЬ

RUN apk add --no-cache python3 libffi-dev libressl-dev eudev-dev libstdc++ nmap && \SHELLКОПИРОВАТЬ

Сохраняем Dockerfile, собираем образ и пересоздаем контейнер:

docker-compose build
docker-compose up -dSHELLКОПИРОВАТЬ

Я дома =)
Я дома =)

Немного Portainer:

-14

Обновление

Для того, что бы обновить наши сервисы до последних версий, нужно выполнить в консоли:

cd /home/pi/smarthome
docker-compose pull
docker-compose build
docker-compose up -dSHELLКОПИРОВАТЬ

Итог

Второй вариант, весьма нетривиален, и новичку покажется не прост в настройке, но при помощи его можно не плохо так сократить размер образа HA. Если вам это не нужно, и у вас достаточно места на диске, рекомендую использовать первый вариант развертывания Home Assistant в Docker. 

Структура каталогов и файлов:

-- smarthome
|-- docker-compose.yml
|-- homeassistant
| |-- config
| `-- Dockerfile
|-- mosquitto
| |-- config
| | |-- mosquitto.conf
| | `-- passwd
| |-- data
| `-- log
|-- portainer
`-- zigbee2mqttHTTPКОПИРОВАТЬ

docker-compose.yml

version: '3.3'

services:

portainer:
container_name: portainer
image: portainer/portainer:1.19.2
restart: always
ports:
- 9000:9000
volumes:
- ./portainer:/data
- /var/run/docker.sock:/var/run/docker.sock

eclipse-mosquitto:
container_name: mosquitto
image: eclipse-mosquitto:latest
restart: always
volumes:
- ./mosquitto/config:/mosquitto/config
- ./mosquitto/data:/mosquitto/data
- ./mosquitto/log:/mosquitto/log
ports:
- 1883:1883
user: '1000:1000'

zigbee2mqtt:
container_name: zigbee2mqtt
image: koenkk/zigbee2mqtt:arm32v6 # arm32 (raspberry pi)
#image: koenkk/zigbee2mqtt:latest # x86_64/amd64
restart: always
volumes:
- ./zigbee2mqtt:/app/data
devices:
- /dev/serial/by-id/usb-Texas_Instruments_TI_CC2531_USB_CDC___0X00124B0014BDEB9C-if00:/dev/ttyACM0
user: '1000:20'

homeassistant:
container_name: homeassistant
#build: ./homeassistant
image: homeassistant/raspberrypi3-homeassistant # arm32
#image: homeassistant/home-assistant # x86_64/amd64
volumes:
- ./homeassistant/config:/config
- /etc/localtime:/etc/localtime:ro
restart: always
network_mode: host
user: '1000:1000'