Вступление
Всем привет.
Не нашел ни одной статьи в базе знаний про докер. Решил наваять одну, чтобы люди, так сказать, могли приобщиться к прекрасному. Сегодня мы будем поднимать сетевой стек для MajorDoMo в Docker.
Плюсы минусы докера, и что это в принципе такое описывать уж не буду...всё давным давно в инете расписано. Сразу к делу.
Установка
Поднимать всё это дело будем используя docker-compose, т.к. там конфиги контейнеров прописаны в одном файле, и не надо за собой таскать длинные строки запуска контейнеров.
Docker
Сперва установим docker и docker-compose. В серверных ОС его можно выбрать как опцию при установке системы, а для остальных:
1 2 3 4 5 6 |
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-серверов и т.п.) через веб интерфейс, тоже в пару кликов, вместо консольного интерфейса.
1 2 |
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 на борту. В принципе там есть инструкция, но я внесу пару корректив в неё))
- Клонируем репозиторий
1git clone https://github.com/A-SOM/docker-majordomo - Клонируется он в текущую папку. Чаще всего при входе через ssh (да и при логине из консоли) вы попадаете в папку пользователя. Так что в папке пользователя должна появится папка master. На этом этапе её можно куда-нибудь перенести, либо переименовать (это конечно можно сделать и при клонировании репозитория, но так проще было объяснить).
1mv master majordomo - Переходим в папку и подтягиваем последнюю версию majordomo
12cd majordomomake clone_code - Далее необходимо немного подправить конфиги (если они уже там не поправлены). Добавляем iputils-ping в устанавливаемые пакеты к любой команде apt-get в Dockerfile образа (необходим для модуля Устройства онлайн)
1nano app-conf/debian/Dockerfile
Я добавил к этой строке
1RUN 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-а (без неё у меня не захотело взлетать)
1nano app-conf/debian/nginx/default.conf
cтроку client_max_body_size 32m; примерно вот так
12345678910server {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;... - Компилить образ автором репозитория предлагается через команду make, но т.к. я планирую использовать данный стэк не только для МД но и для других приложений - придётся так же поправить docker-compose.yml и вместо указанных там переменных вида ${MYSQL_HOST} использовать конечные значение логинов/паролей. В итоге файлик стал выглядеть так:
1nano docker-compose.yml
1234567891011121314151617181920212223242526version: '3'services:majordomo:build: ./app-conf/debian/ports:- '80:80'- '8001:8001'volumes:- './app:/var/www/html'links:- mysqlmysql:image: mariadbports:- '3306:3306'volumes:- ./db-data:/var/lib/mysqlenvironment:- MYSQL_HOST=mysql- MYSQL_ROOT_PASSWORD=mypassword- MYSQL_DATABASE=db_terminal- MYSQL_USER=myuser- MYSQL_PASSWORD=myuserpasswordcommand:mysqld --innodb-flush-method=littlesync --innodb-use-native-aio=OFFrestart: always - После чего можно попробовать скомилить через make install или же через docker (docker-compose up -d) данный образ (точнее 2 образа - для базы и для веб сервера), а так же инициализировать БД.
1make install && make init-db
При инициализации базы будет задан вопрос - удалить ли старую базу? Подтверждаем.
Раньше у меня это работало, но в последний раз у меня make init-db не захотел работать ни в какую. Базу удалял, создавал, но пустую. Дамп не грузился. В итоге пришлось базу заливать вручную через консольный клиент или phpmyadmin (про конфиг которого расскажу чуть позже). - Далее необходимо скопировать конфиг МД
1cp -f ./app/config.php.sample ./app/config.php
и вписать туда (nano ./app/config.php) актуальные данные для подключения к БД. Главное не забывать, что хост для подключения к mysql не localhost а mysql. Логин, пароль и имя базы мы прописывали выше. - Собственно после этого уже должен запустится МД. После правки конфигов нужно перезапустить контейнеры или всю машину.
12docker-compose stopdocker-compose start - Проверяем запустились ли контейнеры
- Заходим на http://айпиадрес, проверяем загрузился ли чистый интерфейс МД.
Mosquitto
Приступим к установке mqtt брокера mosquitto.
Сперва создадим папку, где будут храниться все конфиг файлы и база москита, со всей вложенной структорой.
1 2 3 4 5 6 |
mkdir ./mosquitto mkdir ./mosquitto/config mkdir ./mosquitto/data mkdir ./mosquitto/log touch ./mosquitto/config/mosquitto.conf touch ./mosquitto/config/passwd |
Далее открываем docker-compose.yml и добавляем mosquitto в ряды сервисов, которые там уже есть
1 2 3 4 5 6 7 8 9 10 11 12 13 |
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 |
И пробуем запустить контейнер
1 |
docker-compose up -d |
Если всё прошло успешно (это можно узнать зайдя в portainer, в списке контейнеров, и глянуть в логи сервиса, ну или посмотреть логи через консоль).
На всякий случай заглянем в логи
1 |
tail -f mosquitto/log/mosquitto.log |
А то у меня было такое, что конейнер запустился, а в логах ошибка доступа. Если всё работает, то там должно быть что то типа
1 2 3 4 |
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. |
Теперь можно чуть чуть пошаманить с конфигами. Например создать пользователя:
1 |
docker exec -it mosquitto mosquitto_passwd -c /mosquitto/config/passwd <имя пользователя> |
(при выполнении попросит ввести новый пароль пользователя).
И запретить подключаться гостям (без пользователя) к нашему брокеру
1 |
nano ./mosquitto/config/mosquitto.conf |
1 2 3 4 5 |
persistence true persistence_location /mosquitto/data allow_anonymous false log_dest file /mosquitto/log/mosquitto.log password_file /mosquitto/config/passwd |
После чего можно перезапустить контейнеры, и в очередной раз убедиться, что всё запускается.
Zigbee2MQTT
Как и в случае установки mosquitto - создадим папку под конфиги.
1 |
mkdir ./zigbee2mqtt |
И добавим наш сервис zigbee2mqtt в конец файла docker-compose.yml
1 2 3 4 5 6 7 8 9 10 11 12 |
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 стиком
1 |
sudo usermod -aG dialout <имя_пользователя> |
Пробуем опять создать и запустить контейнеры стака.
1 |
docker-compose up -d |
Контейнер создатстя, но, пока, никуда не подключится, т.к. мы не указывали данные для подключения. А создание и запуск контейнера нужны были, чтобы создать конфигурационные файлы в директории. Теперь можем их отредактировать.
1 |
nano ./zigbee2mqtt/configuration.yaml |
Вписываем/исправляем примерно до следующего вида
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
# разрешаем подключаться новым девайсам (активируем режим сопряжения при запуске) permit_join: true # Настройки MQTT mqtt: # MQTT базовый топик для публикации сообщений base_topic: zigbee2mqtt # MQTT URL server: 'mqtt://mosquitto' #да именно так, т.к. мы хост указали в контейнере москита # MQTT авторизация, если требуется user: user password: password # Настройки порта serial: # Путь к стику CC2531 port: /dev/ttyACM0 |
И перезапускаем контейнер
1 |
docker-compose restart zigbee2mqtt |
В очередной раз видим, что контейнер вполне себе запустился. Так же на скрине я отметил ссылку перехода к логам контейнера. Там можно в "режиме онлайн" наблюдать логи процесса. Если всё настроено правильно - лог будет выглядеть примерно так:
Для тех у кого несколько ком-портов на компе - можно подцепить устройство по серийному номеру. Для начала найдём его
1 |
ls /dev/serial/by-id/usb-* |
Среди результатов найти стик, думаю не проблема
На всякий случай скажу, что искать что то содержащее Texas_Instruments)).
PhpMyAdmin
Многим нужен для комфортной работы phpmyadmin (интерфейс для доступа к базе данных). Решил показать на всякий случай, как его тоже добавить. Но я думаю суть вы уже уловили))) Добавляем очередной сервис в docker-compose.yml
1 2 3 4 5 6 7 8 9 10 11 |
phpmyadmin: image: phpmyadmin/phpmyadmin container_name: phpmyadmin environment: - PMA_HOST=mysql - PMA_PORT=3306 restart: always ports: - 8085:80 depends_on: - mysql |
И поднимаем всю связку
1 |
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, и там прописываем конфигурацию сети.
1 2 3 4 5 6 |
networks: majordomo: driver: bridge ipam: config: - subnet: 172.1.0.0/16 |
Указание статичных адресов контейнеров
После того как указали параметры сети - можно присвоить статичные адреса контейнерам. Рекомендую не занимать первые адреса в сети, либо же указывать адреса всем контейнерам без исключения. Т.к., допустим, если вы указали адрес 172.1.0.2 контейнеру, контейнер, которому адрес не присвоен может занять его, если запустится раньше, и контейнер с указанным адресом не сможет запуститься вовсе. Для контейнера статичный ip присваивается следующим образом (на примере phpmyadmin)
1 2 3 4 5 6 7 8 9 10 11 12 |
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 примерно слежующее
1 |
- './zigbee2mqtt/log:/opt/zigbee2mqtt/data/log' |
И логи появились на нужной страничке
Заключение
Итак все установки закончены, стак функционирует.
Мой финальный конфиг docker-compose.yml выглядит так:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 |
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. Для АРМ-подобных процессоров инструкции могут отличаться от приведённых.
Спасибо за внимание).