Установка в Docker

Материал из MajorDoMo инфо

Установка 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, который, собственно, только что и создали.

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, в списке контейнеров, и глянуть в логи сервиса, ну или посмотреть логи через консоль).

Контейнеры МД2

На всякий случай заглянем в логи

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
containers_md3

В очередной раз видим, что контейнер вполне себе запустился. Так же на скрине я отметил ссылку перехода к логам контейнера. Там можно в "режиме онлайн" наблюдать логи процесса. Если всё настроено правильно - лог будет выглядеть примерно так:

z2mqtt_log

Для тех у кого несколько ком-портов на компе - можно подцепить устройство по серийному номеру. Для начала найдём его

ls /dev/serial/by-id/usb-*

Среди результатов найти стик, думаю не проблема

lsconsole

На всякий случай скажу, что искать что то содержащее 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.

phpmyadmin

Для входа можно использовать юзера root или же пользователя под которым входит majordomo. Оба пароля мы прописывали при поднятии контейнера mysql/mariadb.

Ещё пару слов о докере

На последок ещё пару твиков которые могут понадобиться при использовании докера

Сеть в докере

Как вы, наверное, успели заметить в том же портэйнере отображаются адреса контейнеров. По скольку контейнеры это изолированные среды, а изолированные среды должны как то общаться между собой и с пользователем - связывает их виртуальная сеть, поднятая прямо на сервере. У сети есть своё пространство имён, каждый контейнер имеет свой адрес. Нет, есть, конечно, и другие типы интерфейсов сети, но о них я не упоминаю, т.к. в текущей статье использовался только тип интерфейса bridge. Если мы обращаемся к приложению в контейнере прямо с серверной машины - надо обращаться не к localhost (127.0.0.1), как мы привыкли это делать, а к ip адресу, присвоенному контейнеру. Так же некоторые контейнеры позволяют для подключения использовать DNS имя, чем мы собственно и воспользовались при настройке mosquitto и mariadb. Например чтобы подключиться модулем zigbee2mqtt к брокеру mosquitto надо указать примерно следующие настройки

Z2mconfig-1

Указание параметров сети

Если хотите указать какие-либо параметры сети, отличающиеся от выдаваемых по дефолту - для этого нужно обозначить сеть в конфиге. Делается это уже за пределами секции 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'

И логи появились на нужной страничке

z2m_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. Для АРМ-подобных процессоров инструкции могут отличаться от приведённых.

Спасибо за внимание).