Установка в Docker
Установка Majordomo+mosquitto+zigbee2mqtt в Docker
Вступление
Всем привет.
Не нашел ни одной статьи в базе знаний про докер. Решил наваять одну, чтобы люди, так сказать, могли приобщиться к прекрасному. Сегодня мы будем поднимать сетевой стек для MajorDoMo в Docker.
Плюсы минусы докера, и что это в принципе такое описывать уж не буду...всё давным давно в инете расписано. Сразу к делу.
Установка
Поднимать всё это дело будем используя docker-compose, т.к. там конфиги контейнеров прописаны в одном файле, и не надо за собой таскать длинные строки запуска контейнеров.
Docker
Сперва установим docker и docker-compose. В серверных ОС его можно выбрать как опцию при установке системы, а для остальных:
sudo apt get update
sudo apt get upgrade
sudo apt-get install docker docker-compose
sudo usermod -aG docker <имя_пользователя>
sudo reboot
Portainer
Так же можно (но не обязательно) установить Portainer дабы созерцать в веб интерфейсе, что за контейнеры у нас создаются, и каким образом. Так же там можно будет глянуть логи. Но и то и то можно сделать в консоли, так что пункт скорее чтобы продемонстрировать преимущества докера - в одну команду (создание тома portainer_data считать не будем, т.к. можно и без него) поднимается довольно мощный сервис. Так же новичкам, может, будет удобнее, создавать контейнеры для различных standalone приложений (типа качалки торрентов, всяких plex-серверов и т.п.) через веб интерфейс, тоже в пару кликов, вместо консольного интерфейса.
docker volume create portainer_data
docker run -d -p 8000:8000 -p 9000:9000 -v /var/run/docker.sock:/var/run/docker.sock -v portainer_data:/data portainer/portainer
После чего портэйнер должен запуститься на 9000 порту нашего сервера. При первом входе будет предложено создать пароль администратора, и подключиться к сокету докера. Выбираем локальную машинку, и видим один запущенный контейнер portainer, который, собственно, только что и создали.
MajorDoMo
Далее переходим к majordomo.
Будем использовать уже готовый репозиторий
https://github.com/A-SOM/docker-majordomo
Он уже идёт как связка 2х контейнеров sql и debian с php и nginx на борту. В принципе там есть инструкция, но я внесу пару корректив в неё))
1 Клонируем репозиторий
git clone https://github.com/A-SOM/docker-majordomo
2 Клонируется он в текущую папку. Чаще всего при входе через ssh (да и при логине из консоли) вы попадаете в папку пользователя. Так что в папке пользователя должна появится папка master. На этом этапе её можно куда-нибудь перенести, либо переименовать (это конечно можно сделать и при клонировании репозитория, но так проще было объяснить).
mv master majordomo
3 Переходим в папку и подтягиваем последнюю версию majordomo
cd majordomo
make clone_code
4 Далее необходимо немного подправить конфиги (если они уже там не поправлены). Добавляем iputils-ping в устанавливаемые пакеты к любой команде apt-get в Dockerfile образа (необходим для модуля Устройства онлайн)
nano app-conf/debian/Dockerfile
Я добавил к этой строке
RUN apt-get install php php-cgi php-cli php-pear php-mysql php-mbstring php-xml php-fpm curl libcurl3 libcurl3-dev php-curl iputils-ping -y
а так же в конфиг nginx-а (без неё у меня не захотело взлетать)
nano app-conf/debian/nginx/default.conf
cтроку client_max_body_size 32m; примерно вот так
server { listen 80 default_server; index index.php index.html index.htm; server_name 127.0.0.1 localhost _; set $MAGE_ROOT /var/www/html; error_log /var/log/nginx/error.log; access_log /var/log/nginx/access.log upstream_time; root $MAGE_ROOT; client_max_body_size 32m; ...
5 Компилить образ автором репозитория предлагается через команду make, но т.к. я планирую использовать данный стэк не только для МД но и для других приложений - придётся так же поправить docker-compose.yml и вместо указанных там переменных вида ${MYSQL_HOST} использовать конечные значение логинов/паролей. В итоге файлик стал выглядеть так:
nano docker-compose.yml
version: '3' services: majordomo: build: ./app-conf/debian/ ports: - '80:80' - '8001:8001' volumes: - './app:/var/www/html' links: - mysql mysql: image: mariadb ports: - '3306:3306' volumes: - ./db-data:/var/lib/mysql environment: - MYSQL_HOST=mysql - MYSQL_ROOT_PASSWORD=mypassword - MYSQL_DATABASE=db_terminal - MYSQL_USER=myuser - MYSQL_PASSWORD=myuserpassword command: mysqld --innodb-flush-method=littlesync --innodb-use-native-aio=OFF restart: always
6 После чего можно попробовать скомилить через make install или же через docker (docker-compose up -d) данный образ (точнее 2 образа - для базы и для веб сервера), а так же инициализировать БД.
make install && make init-db
При инициализации базы будет задан вопрос - удалить ли старую базу? Подтверждаем. Раньше у меня это работало, но в последний раз у меня make init-db не захотел работать ни в какую. Базу удалял, создавал, но пустую. Дамп не грузился. В итоге пришлось базу заливать вручную через консольный клиент или phpmyadmin (про конфиг которого расскажу чуть позже).
6 Далее необходимо скопировать конфиг МД
cp -f ./app/config.php.sample ./app/config.php
и вписать туда (nano ./app/config.php) актуальные данные для подключения к БД. Главное не забывать, что хост для подключения к mysql не localhost а mysql. Логин, пароль и имя базы мы прописывали выше.
8 Собственно после этого уже должен запустится МД. После правки конфигов нужно перезапустить контейнеры или всю машину.
docker-compose stop
docker-compose start
9 Проверяем запустились ли контейнеры
Заходим на http://айпиадрес, проверяем загрузился ли чистый интерфейс МД.
Mosquitto
Приступим к установке mqtt брокера mosquitto.
Сперва создадим папку, где будут храниться все конфиг файлы и база москита, со всей вложенной структорой.
mkdir ./mosquitto
mkdir ./mosquitto/config
mkdir ./mosquitto/data
mkdir ./mosquitto/log
touch ./mosquitto/config/mosquitto.conf
touch ./mosquitto/config/passwd
Далее открываем docker-compose.yml и добавляем mosquitto в ряды сервисов, которые там уже есть
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' environment: - MQTT_BROKER_URL=mqtt://mosquitto
И пробуем запустить контейнер
docker-compose up -d
Если всё прошло успешно (это можно узнать зайдя в portainer, в списке контейнеров, и глянуть в логи сервиса, ну или посмотреть логи через консоль).
На всякий случай заглянем в логи
tail -f mosquitto/log/mosquitto.log
А то у меня было такое, что конейнер запустился, а в логах ошибка доступа. Если всё работает, то там должно быть что то типа
1565844759: mosquitto version 1.6.4 starting 1565844759: Config loaded from /mosquitto/config/mosquitto.conf. 1565844759: Opening ipv4 listen socket on port 1883. 1565844759: Opening ipv6 listen socket on port 1883.
Теперь можно чуть чуть пошаманить с конфигами. Например создать пользователя:
docker exec -it mosquitto mosquitto_passwd -c /mosquitto/config/passwd <имя пользователя>
(при выполнении попросит ввести новый пароль пользователя).
И запретить подключаться гостям (без пользователя) к нашему брокеру
nano ./mosquitto/config/mosquitto.conf
persistence true persistence_location /mosquitto/data allow_anonymous false log_dest file /mosquitto/log/mosquitto.log
password_file /mosquitto/config/passwd
После чего можно перезапустить контейнеры, и в очередной раз убедиться, что всё запускается.
Zigbee2MQTT
Как и в случае установки mosquitto - создадим папку под конфиги.
mkdir ./zigbee2mqtt
И добавим наш сервис 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/ttyACM0:/dev/ttyACM0 user: '1000:20' depends_on: - mosquitto
Не забываем добавить пользователя в группу dialout (20), чтобы он смог работать с usb стиком
sudo usermod -aG dialout <имя_пользователя>
Пробуем опять создать и запустить контейнеры стака.
docker-compose up -d
Контейнер создатстя, но, пока, никуда не подключится, т.к. мы не указывали данные для подключения. А создание и запуск контейнера нужны были, чтобы создать конфигурационные файлы в директории. Теперь можем их отредактировать.
nano ./zigbee2mqtt/configuration.yaml
Вписываем/исправляем примерно до следующего вида
# разрешаем подключаться новым девайсам (активируем режим сопряжения при запуске) permit_join: true # Настройки MQTT mqtt: # MQTT базовый топик для публикации сообщений base_topic: zigbee2mqtt # MQTT URL server: 'mqtt://mosquitto' #да именно так, т.к. мы хост указали в контейнере москита # MQTT авторизация, если требуется user: user password: password # Настройки порта serial: # Путь к стику CC2531 port: /dev/ttyACM0
И перезапускаем контейнер
docker-compose restart zigbee2mqtt
В очередной раз видим, что контейнер вполне себе запустился. Так же на скрине я отметил ссылку перехода к логам контейнера. Там можно в "режиме онлайн" наблюдать логи процесса. Если всё настроено правильно - лог будет выглядеть примерно так:
Для тех у кого несколько ком-портов на компе - можно подцепить устройство по серийному номеру. Для начала найдём его
ls /dev/serial/by-id/usb-*
Среди результатов найти стик, думаю не проблема
На всякий случай скажу, что искать что то содержащее Texas_Instruments)).
PhpMyAdmin
Многим нужен для комфортной работы phpmyadmin (интерфейс для доступа к базе данных). Решил показать на всякий случай, как его тоже добавить. Но я думаю суть вы уже уловили))) Добавляем очередной сервис в docker-compose.yml
phpmyadmin: image: phpmyadmin/phpmyadmin container_name: phpmyadmin environment: - PMA_HOST=mysql - PMA_PORT=3306 restart: always ports: - 8085:80 depends_on: - mysql
И поднимаем всю связку
docker-compose up -d
Phpmyadmin доступен на порту http://<айпиадрес_сервера>:8085.
Для входа можно использовать юзера root или же пользователя под которым входит majordomo. Оба пароля мы прописывали при поднятии контейнера mysql/mariadb.
Ещё пару слов о докере
На последок ещё пару твиков которые могут понадобиться при использовании докера
Сеть в докере
Как вы, наверное, успели заметить в том же портэйнере отображаются адреса контейнеров. По скольку контейнеры это изолированные среды, а изолированные среды должны как то общаться между собой и с пользователем - связывает их виртуальная сеть, поднятая прямо на сервере. У сети есть своё пространство имён, каждый контейнер имеет свой адрес. Нет, есть, конечно, и другие типы интерфейсов сети, но о них я не упоминаю, т.к. в текущей статье использовался только тип интерфейса bridge. Если мы обращаемся к приложению в контейнере прямо с серверной машины - надо обращаться не к localhost (127.0.0.1), как мы привыкли это делать, а к ip адресу, присвоенному контейнеру. Так же некоторые контейнеры позволяют для подключения использовать DNS имя, чем мы собственно и воспользовались при настройке mosquitto и mariadb. Например чтобы подключиться модулем zigbee2mqtt к брокеру mosquitto надо указать примерно следующие настройки
Указание параметров сети
Если хотите указать какие-либо параметры сети, отличающиеся от выдаваемых по дефолту - для этого нужно обозначить сеть в конфиге. Делается это уже за пределами секции services. Создаём отдельную секцию networks, и там прописываем конфигурацию сети.
networks: majordomo: driver: bridge ipam: config: - subnet: 172.1.0.0/16
Указание статичных адресов контейнеров
После того как указали параметры сети - можно присвоить статичные адреса контейнерам. Рекомендую не занимать первые адреса в сети, либо же указывать адреса всем контейнерам без исключения. Т.к., допустим, если вы указали адрес 172.1.0.2 контейнеру, контейнер, которому адрес не присвоен может занять его, если запустится раньше, и контейнер с указанным адресом не сможет запуститься вовсе. Для контейнера статичный ip присваивается следующим образом (на примере phpmyadmin)
phpmyadmin: image: phpmyadmin/phpmyadmin container_name: phpmyadmin networks: majordomo: ipv4_address: 172.1.0.20 environment: - PMA_HOST=mysql - PMA_PORT=3306 restart: always ports: - 8085:80
После этого из локальной машинки можно будет обращаться к контейнеру по указанному ip адресу...напоминаю - эта сеть существует только "внутри сервера". Снаружи - все сервисы доступны только по ip-адресу сервера и прокинутым наружу портам (по крайней мере в режиме сети bridge)
Логи Zigbee2MQTT Ну и ещё один лайфхак на последок. Я уже показывал что логи того же zigbee2mqtt доступны в портэйнере. Так же, на примере москита показывал как их можно просмотреть в консоли. В модуле же zigbee2mqtt так же реализован онлайн мониторинг логов. Но чтобы он завёлся - нам нужно прокинуть соответствующую папку в контейнер МД. Т.е. дописать в секцию volumes примерно слежующее
- './zigbee2mqtt/log:/opt/zigbee2mqtt/data/log'
И логи появились на нужной страничке
Заключение
Итак все установки закончены, стак функционирует.
Мой финальный конфиг docker-compose.yml выглядит так:
version: '3' services: majordomo: build: ./app-conf/debian/ ports: - '80:80' - '8001:8001' networks: majordomo: ipv4_address: 172.1.0.5 volumes: - './app:/var/www/html' - './zigbee2mqtt/log:/opt/zigbee2mqtt/data/log' links: - mysql mysql: image: mariadb ports: - '3306:3306' networks: majordomo: ipv4_address: 172.1.0.1 volumes: - ./db-data:/var/lib/mysql environment: - MYSQL_HOST=mysql - MYSQL_ROOT_PASSWORD=rootpassword - MYSQL_DATABASE=db_terminal - MYSQL_USER=user - MYSQL_PASSWORD=mypassword command: mysqld --innodb-flush-method=littlesync --innodb-use-native-aio=OFF restart: always mosquitto: container_name: mosquitto image: eclipse-mosquitto:latest restart: always volumes: - ./mosquitto/config:/mosquitto/config - ./mosquitto/data:/mosquitto/data - ./mosquitto/log:/mosquitto/log networks: majordomo: ipv4_address: 172.1.0.100 ports: - 1883:1883 user: '1000:1000' environment: - MQTT_BROKER_URL=mqtt://mosquitto zigbee2mqtt: container_name: zigbee2mqtt 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___0X00124B001938AB48-if00:/dev/ttyACM0 user: '1000:20' networks: - majordomo depends_on: - mosquitto phpmyadmin: image: phpmyadmin/phpmyadmin container_name: phpmyadmin networks: majordomo: ipv4_address: 172.1.0.20 environment: - PMA_HOST=172.1.0.1 - PMA_PORT=3306 restart: always ports: - 8085:80 depends_on: - mysql qbittorrent: image: wernight/qbittorrent:latest container_name: qbittorrent volumes: - ./qbittorrent/config:/config - /mnt/mywd/-=Downloads=-/torrent:/downloads - ./qbittorrent/torrents:/torrents user: '1000:1000' ports: - '6881:6881' - '6881:6881/udp' - '9090:9090' networks: majordomo: ipv4_address: 172.1.0.30 restart: unless-stopped blynk-server: container_name: blynk-server image: mpherg/blynk-server:latest networks: majordomo: ipv4_address: 172.1.0.40 ports: - '8080:8080' - '8440:8440' - '9443:9443' restart: always volumes: - ./blynk/data:/config - ./blynk/backup:/data/ networks: majordomo: driver: bridge ipam: config: - subnet: 172.1.0.0/16
Можно приступать к использованию majordomo, а так же прикладных модулей в виде mosquitto и zigbee2mqtt. Как вы можете заметить - дописал ещё пару сервисов для личного использования. Стак поднимался на архетектуре x86_64. Для АРМ-подобных процессоров инструкции могут отличаться от приведённых.
Спасибо за внимание).