Вводная
Ранее не писал статьи, делал только для себя гайды/шпаргалки, что бы не забыть. Так что это мой первый опыт. Предупреждаю сразу, внизу будет много 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
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КОПИРОВАТЬ
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КОПИРОВАТЬ
sudo usermod -a -G dialout piSHELLКОПИРОВАТЬ
Запускаем контейнер c zigbee2mqtt:
cd /home/pi/smarthome/
docker-compose up -dSHELLКОПИРОВАТЬ
После развертывания нашего контейнера, в папке /home/pi/smarthome/zigbee2mqtt будут находиться конфигурационные файлы zigbee2mqtt.
ls -lia /home/pi/smarthome/zigbee2mqttSHELLКОПИРОВАТЬ
# 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КОПИРОВАТЬ
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КОПИРОВАТЬ
#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 - вариант №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КОПИРОВАТЬ
# 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:
Обновление
Для того, что бы обновить наши сервисы до последних версий, нужно выполнить в консоли:
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'