1. Сконфигурируйте параметры сервера, на который будет производиться установка платформы умного дома в файле /etc/ansible-iot/latest/inventory.

sudo nano /etc/ansible-iot/latest/inventory

Структура разделов iot, mqtt_broker и olap_service в файле/etc/ansible-iot/latest/inventory:

inventory
[iot]
localhost       ansible_connection=local        ansible_sudo_pass=password
[mqtt_broker]
localhost       ansible_connection=local        ansible_sudo_pass=password
[rabbitmq]
localhost       ansible_connection=local        ansible_sudo_pass=password
[olap]
localhost       ansible_connection=local        ansible_sudo_pass=password
[clickhouse]
localhost       ansible_connection=local        ansible_sudo_pass=password
[core]
localhost       ansible_connection=local        ansible_sudo_pass=password
[wsproxy]
localhost       ansible_connection=local        ansible_sudo_pass=password
[zwayproxy]
localhost       ansible_connection=local        ansible_sudo_pass=password
[monitoring]
localhost       ansible_connection=local        ansible_sudo_pass=password
[elk]
localhost       ansible_connection=local        ansible_sudo_pass=password
[slgate]
localhost       ansible_connection=local        ansible_sudo_pass=password
[evi_server]
localhost       ansible_connection=local        ansible_sudo_pass=password
[minio]
localhost       ansible_connection=local        ansible_sudo_pass=password
[peeper]
localhost       ansible_connection=local        ansible_sudo_pass=password

Описание основных параметров платформы умного дома в файле inventory:

ПараметрЗначение по умолчаниюТребуемое значениеОписание
<без имени>localhostlocalhost

Адрес сервера, на который будет производиться установка сервиса.

Так как предполагается локальная установка, используется значение localhost.

ansible_connection
locallocal

Способ подключения к серверу.

local — локальное подключение.

ansible_sudo_pass
passwordpassword

Пароль для получения привилегий суперпользователя.




2. Сконфигурируйте параметры для установки платформы умного дома в файле /etc/ansible-iot/latest/vars/default.yml

sudo nano /etc/ansible-iot/latest/vars/default.yml

Базовая структура разделов iot в файле/etc/ansible-iot/latest/vars/default.yml:

default.yml
# Параметры установки платформы.
iot:
  # Имя (IP-адрес) сервера, на котором будет производиться развертывание платформы IoT.
  #  ВАЖНО!!! В 'serverName' нужно прописывать то имя (IP-адрес), по которому будет доступны платформа.
  serverName: "external.iot.address"
  # Содержит путь до директории, в которую будет произведена установка.
  installDir: /storage/iot
  # Ссылка на политику конфиденциальности
  privacyPolicyUrl: "my.privacy.policy"
  # Ссылка на базу знаний
  knowledgeBaseUrl: "https://docs.eltex-co.ru/display/EKB/IoT"

  # Параметры MongoDB.
  mongodb:
    # Версия MongoDB. На старом железе, не поддерживающем оптимизацию, нужно выставить значение `4`.
    version: 6
    external:
      # Если выставлен в true, будет использоваться внешняя MongoDB.
      # ВАЖНО!!! MongoDB должна быть настроена, а параметры подключения нужно указать в 'uri'.
      enable: false
      # URI внешней MongoDB.
      uri: "mongodb://external.mongodb.address:27017"

  # Параметры WEB.
  web:
    # Порт HTTP, по которому будет осуществляться доступ в WEB.
    httpPort: 80
    # Порт HTTPS, по которому будет осуществляться доступ в WEB.
    httpsPort: 443
    # Автоматически перенаправлять запросы по порту HTTP на порт HTTPS
    redirectHttpToHttps: true
    # Нужно ли использовать HTTPS при формировании ссылок к WEB ('true' по умолчанию, при этом будет использован порт,
    # указанный в 'iot.web.httpsPort'). Если поставить в 'false', будет использован HTTP и порт,
    # указанный в 'iot.web.httpPort'.
    useHttpsByDefault: true
    nginx:
      # Максимальное число соединений, которые одновременно может открыть рабочий процесс
      worker_connections: 2048
      # Ограничение скорости обработки запросов модулем Nginx Rate Limiting
      rateLimit:
        enable: true
    certbot:
      # Использовать ли certbot для получения сертификатов Let's Encrypt.
      enable: false
      # Email владельца домена. Необходим для подтверждения валидности домена при получении сертификата Let's Encrypt.
      email: test@email.com
    fail2ban:
      enable: true

  # Параметры сервера отправки email.
  mail:
    smtp:
      submitter: test@email.com
      password: "password"
      senderPrefix: "Сервер Eltex-SC"
      auth: "true"
      host: email.com
      port: 587
      # Протокол шифрования, используемый при подключении к серверу. Допустимые значения: none, starttls, ssl.
      protection: starttls
  push:
    firebase:
      enabled: false
    apns:
      enabled: false
    hms:
      enabled: false

  # Параметры установки сервиса платежей для тарифов.
  payment:
    logLevel: INFO

  # Параметры authorization server.
  authorization:
    # Уровень отладки внутри IoT Authorization Server.
    logLevel: INFO

    # Уровень сложности капчи: easy, medium, hard
    captchaLevel: "easy"

    # Параметры для управления доступностью саморегистрации.
    selfRegistration:
      allow: true
      allowDemo: true
      allowSocialNetworks: false

    # Параметры клиентских регистраций (через соцсети).
    clientRegistrations:
      google:
        enable: true
        clientId: "GoogleClientIdChangeMe"
        clientSecret: "GoogleClientSecretChangeMe"
      microsoft:
        enable: true
        clientId: "MicrosoftClientIdChangeMe"
        clientSecret: "MicrosoftClientSecretChangeMe"
      apple:
        enable: true
        clientId: "AppleClientIdChangeMe"
        keyId: "AppleKeyIdChangeMe"
        teamId: "AppleTeamIdChangeMe"
      yandex:
        enable: true
        clientId: "YandexClientIdChangeMe"
        clientSecret: "YandexClientSecretChangeMe"
      vk:
        enable: true
        clientId: "VkClientIdChangeMe"
        clientSecret: "VkClientSecretChangeMe"
      mailRu:
        enable: true
        clientId: "MailRuClientIdChangeMe"
        clientSecret: "MailRuClientSecretChangeMe"

    skills:
      # Параметры навыка Яндекс для интеграции с Умным домом (Алисой). Отображается в карточке навыка.
      yandex:
        enabled: false
        # Параметры для Basic Authentication.
        clientId: "YandexClientIdChangeMe"
        password: "PasswordChangeMe"
        # Id навыка, который необходимо указывать при отправке уведомлений.
        skillId: ""
        # OAuth-токен, который необходимо указывать при отправке уведомлений.
        oauthToken: ""

      # Параметры проекта умного дома Сбера для интеграции с Салютом. Отображается в карточке проекта.
      sber:
        enabled: false
        # Параметры для Basic Authentication.
        clientId: "SberClientIdChangeMe"
        password: "PasswordChangeMe"
        # Bearer-токен, который необходимо указывать при отправке уведомлений.
        bearerToken: ""

      # Параметры проекта умного дома Mail.ru для интеграции с Марусей. Отображается в карточке проекта/приложения.
      marusya:
        enabled: false
        # Параметры для Basic Authentication.
        clientId: "MarusyaClientIdChangeMe"
        password: "PasswordChangeMe"
        # App ID, который был назначен приложению VK при создании.
        appId: "MarusyaAppIdChangeMe"
        # OAuth-токен, который необходимо указывать при отправке уведомлений.
        oauthToken: ""

  # Параметры платформы IoT core.
  core:
    # Уровень отладки внутри IoT Core.
    logLevel: INFO

    # Порты платформы для подключения zway-контроллеров.
    ctlGate:
      port: 8070
      tcpPort: 8069
      sslPort: 8072

    links:
      # Нужно ли использовать HTTPS при формировании ссылок к ресурсам самой платформы (например, прошивки).
      useHttpsForApi: false
      # Нужно ли использовать HTTPS при формировании ссылок на фото с камер наблюдения.
      useHttpsForCameraLinks: true
      # Нужно ли использовать HTTPS при загрузке превью с камеры видеонаблюдения в систему.
      useHttpsForCameraPreviewUpload: true
      # Нужно ли использовать 'iot.web.httpPort'/'iot.web.httpsPort' при формировании ссылок к API.
      useUiProxyForApi: true

    # Параметры для работы с видеосерверами
    video:
      # Параметры Flussonic.
      flussonic:
        url: ""
        apiKey: ""
        operatorId: ""
        adminLogin: ""
        motion:
          enabled: false
      # Параметры видеосервера EVI
      evi:
        url: ""
        apiKey: ""
        operatorId: ""
        adminLogin: ""

    # Настройки ИК-пульта.
    irc:
      # Время ожидания ИК команды от пользователя
      recTimeout: 15s
      # Таймаут записи команды (отсутствия фронтов)
      cmdTimeout: 100ms

    # Настройки охраны.
    guard:
      # Время, которое дается на включение FLIRS устройств (ждем подтверждение от контроллера),
      # при постановке на охрану.
      deviceRequestDelay: 15s
      # Время, которое прибавляется ко времени задержки на очистку охранного кэша при постановке/снятия с охраны,
      # на случай если охрана не завершила процесс постановки/снятия.
      # Время задержки формируется как количество охранных устройств умноженное на deviceRequestDelay.
      clearContextExtraCacheDelay: 1m

# Параметры установки сервисов логирования (Elasticsearch + Logstash + Kibana).
elk:
  # Нужно ли добавлять в платформу appender, отправляющий логи в logstash.
  # В нем нет необходимости, если ELK не развернут или не настроен; это лишь спровоцирует сообщения об ошибках отправки
  # в логах платформы.
  enable: false
  # Имя (IP-адрес) сервера, на котором будет развернут ELK.
  # По умолчанию совпадает с 'iot.serverName', что предполагает установку рядом с платформой (на том же хосте).
  # В таком случае хосты в инвентаре в группах [iot] и [elk] должны совпадать.
  serverName: "{{ iot.serverName }}"
  # Директория для установки системы логирования.
  installDir: /storage/elk

slgate:
  # Имя сервера, на котором будет развернут SLGATE.
  # ВАЖНО!!! Нельзя использовать IP-адрес, т.к. такая схема не будет работать!
  # По умолчанию совпадает с 'iot.serverName', что предполагает установку рядом с платформой (на том же хосте).
  # В таком случае хосты в инвентаре в группах [iot] и [slgate] должны совпадать.
  serverName: "{{ iot.serverName }}"
  # Директория для установки SLGATE.
  installDir: /storage/slgate

# Параметры установки сервера видеонаблюдения.
evi:
  serverName: "{{ iot.serverName }}"
  # Директория для установки системы мониторинга.
  installDir: /storage/evi

Описание основных параметров платформы умного дома в файле default.yml:

Жирным шрифтом выделены параметры, значения которых необходимо задать, опираясь на столбец "Значение по умолчанию", с учетом ваших индивидуальных требований.

ПараметрЗначение по умолчаниюТребуемое значениеОписание

iot.serverName

"external.iot.address"

Доменное имя платформы умного дома

Адрес платформы умного дома.
Данный адрес должен быть доступен для запросов из внешней сети.

iot.installDir

/storage/iot

/storage/iot

Путь к директории, где будут храниться данные платформы умного дома.

 iot.privacyPolicyUrl

"my.privacy.policy"

URL страницы политики конфиденциальности платформы умного дома

Ссылка на политику конфиденциальности платформы умного дома.
Открывается при нажатии на кнопку "Политика конфиденциальности"

 iot.knowledgeBaseUrl

"https://docs.eltex-co.ru/display/EKB/IoT"

URL базы знаний платформы умного дома 

Ссылка на базу знаний платформы умного дома.
Открывается при нажатии на кнопку "Нужна помощь?"

iot.web.httpPort

80

80

Порт HTTP, по которому будет осуществляться доступ в веб-интерфейс и к API платформы умного дома.

iot.web.httpsPort

443

443

Порт HTTPS, по которому будет осуществляться доступ в веб-интерфейс и к API платформы умного дома.

iot.web.redirectHttpToHttps

true

true

Автоматическое перенаправление запросов с порта HTTP на порт HTTPS.

iot.web.useHttpsByDefault

true

true

Нужно ли использовать HTTPS при формировании ссылок на веб-интерфейс.

iot.web.nginx.rateLimit.enable

true

true

Включение ограничения скорости обработки запросов с одного IP-адреса веб-сервером.

iot.web.certbot.enable

true

true

Включение автоматического получения SSL сертификата Let's Encrypt.

iot.web.certbot.email

test@email.com

Адрес электронной почты, к которому будет привязан SSL-сертификат Let's Encrypt

Адрес электронной почты, к которому будет привязан полученный SSL сертификат Let's Encrypt. Необходим для подтверждения валидности домена при получении сертификата Let's Encrypt.

iot.web.fail2ban.enable

true

false

Включение блокировки IP-адресов, вызывающих ошибки веб-сервера и превышающих лимиты ограничения скорости запросов (если активен параметр iot.web.nginx.rateLimit.enable).

iot.mail.smtp.submitter

test@email.com

Адрес электронной почты для отправки писем платформой умного дома

Адрес электронной почты, от имени которого будут отправляться электронные письма платформой умного дома.

iot.mail.smtp.password

"password"

Пароль для указанного адреса электронной почты

Пароль для указанного выше адреса электронной почты.

iot.mail.smtp.senderPrefix

"Сервер Eltex-SC"

"Сервер Eltex-SC"

Имя отправителя, с которым будут отправляться электронные письма платформой умного дома.

iot.mail.smtp.auth

"true"

"true"

Использовать аутентификацию при подключении к почтовому серверу.

iot.mail.smtp.host

email.com

Адрес почтового сервера

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

iot.mail.smtp.port

587

Порт почтового сервера

Порт указанного выше почтового сервера.

iot.mail.smtp.protection

starttls

Протокол шифрования, используемый при подключении к почтовому серверу

Протокол шифрования, используемый при подключении к серверу.

Допустимые значения: none, starttls, ssl.

iot.authorization.logLevel

INFO

ERROR

Уровень логирования для сервера авторизации.
Повышение до ERROR позволяет снизить нагрузку на CPU.

Возможные значения: ERROR, WARN, INFO, DEBUG, TRACE.

iot.core.logLevel

INFO

ERROR

Уровень логирования для ядра платформы умного дома.
Повышение до ERROR позволяет снизить нагрузку на CPU.

Возможные значения: ERROR, WARN, INFO, DEBUG, TRACE

iot.core.ctlGate.port

8070

8070

Порт для подключения Z-Wave-контроллера (незащищенное соединение).

Обязательно должен совпадать с iot.zwayproxy.port.map из файла service_parameters.yml

iot.core.ctlGate.sslPort

8072

8072

Порт для подключения Z-Wave-контроллера (защищенное соединение).

Обязательно должен совпадать с iot.zwayproxy.sslPort.map из файла service_parameters.yml

iot.core.links.useHttpsForApi

false

false

Нужно ли использовать HTTPS при формировании ссылок на ресурсы платформы умного дома.

Включение данного параметра может привести к ошибкам обновления прошивки на устройствах, которые не поддерживают HTTPS.

iot.core.push.firebase

false

true

Включение возможности отправки пуш-уведомлений через Firebase Cloud Messaging для Android-приложения Eltex Home.

iot.core.push.apns

false

true

Включение возможности отправки пуш-уведомлений через Apple Push Notification Service для iOS-приложения Eltex Home.

iot.authorization.clientRegistrations.google.enable

true

false

Включение возможности регистрации через учетную запись Google.

iot.authorization.clientRegistrations.microsoft.enable

true

false

Включение возможности регистрации через учетную запись Microsoft.

iot.authorization.clientRegistrations.apple.enable

true

false

Включение возможности регистрации через Apple ID.




3. Сконфигурируйте параметры для работы платформы умного дома в файле/etc/ansible-iot/latest/vars/service_parameters.yml.

sudo nano /etc/ansible-iot/latest/vars/service_parameters.yml

Структура файла /etc/ansible-iot/latest/vars/service_parameters.yml:

service_parameters.yml
# Экземпляр платформы с параметрами по умолчанию.
instance: "IoT-instance-default"

# Версия контейнеров.
release: "2.0.1"

# Имя репозитория docker registry, содержащего docker-образы для развертывания.
registry: hub.eltex-co.ru

# Список сервисов для перезапуска (при запуске плейбуков restart_*.yml).
# Можно оставить пустым, а при запуске передавать параметром командной строки.
services: [ ]

# Нужно ли выполнять подготовку дистрибутива к установке. Этот шаг полезен при "чистой" установке
# на только что созданный сервер. Если ранее уже была выполнена установка компонентов IoT через ansible,
# то такая подготовка не требуется и этот шаг можно пропустить для экономии времени.
withDistroPreparingStep: true

# Суффикс, добавляемый к имени каждого контейнера (помогает избежать конфликты имен контейнеров).
containerNameSuffix: ""

# Добавляет сеть docker "external" с параметром "external: true" к контейнерам.
# Позволяет пробрасывать порты из вне к контейнерам.
# Параметр сделан для сохранения обратной совместимости с прошлыми версиями при интеграции с сетью peeper #395336
# true по-умолчанию, если false - external уходит с контейнеров iot_base, кроме iot-web-mc
networkExternal: true

# Параметры сервисов IoT (для docker-compose), сгруппированные по именам.
# 'enable' - должен ли присутствовать сервис в docker-compose.yml.
# 'port.map' - номер порта сервиса в сети хоста.
# 'port.export' - нужно ли выполнять маппинг порта из контейнера в сеть хоста.
# 'db.name' - имя БД, используемой сервисом (связкой сервисов).
# Для большинства сервисов есть поля external и internal, например: iot.broker.external
# external - для взаимодействия с сервисом развернутым на сторонней машине не через ansible-playbook.
# internal - настройка внутренних подключений со стороны микросервисов при разворачивании через ansible-playbook.
iot:
  swarm:
    enabled: true
    # Имя stack-а для запуска в docker-swarm.
    stack: swarm_iot
  # Параметры мониторинга использования дискового пространства. Должны соответствовать требованию:
  # warnThreshold > criticalThreshold > 0, иначе мониторинг дискового пространства будет отключен.
  diskUsage:
    # Порог дискового пространства (в %), при достижении которого все логгеры микросервисов переводятся в режим WARN
    # (отображаются сообщения с тегами WARN и ERROR). Количество бэкапов баз уменьшается пропорционально приближению к
    # порогу criticalThreshold.
    warnThreshold: 20
    # Порог дискового пространства (в %), при достижении которого все логгеры микросервисов переводятся в режим ERROR
    # (отображаются только сообщения с тегом ERROR). Бэкапы баз не выполняются.
    criticalThreshold: 10
  # использовать сервис Notification для отправки пушей, вместо старой логики
  useNotification: true
  mongodb:
    replication:
      label: has-mongodb
    port:
      map: 27017
      export: false
  broker:
    logLevel: INFO
    replication:
      label: has-broker
    metrics:
      topicCounterEnabled: true
    external:
      # Будет ли развернут брокер на стороннем хосте.
      enable: false
      # Если установка брокера на сторонний хост будет выполняться средствами ansible, то в какую директорию.
      installDir: /storage/iot
      # Внешний адрес стороннего хоста, по которому к брокеру будут подключаться платформа и устройства.
      host: "external.broker.address"
      port:
        map: 8883
    internal:
      port:
        map: 8083
        export: false
    db:
      name: iot-broker
    jconsole:
      enable: false
      port: 32002
      # Необходимо указать адрес хоста, куда будет подключаться jconsole-клиент.
      # При развертывании докера - здесь указывается адреса хоста, где работает докер.
      host: "10.20.30.40"
    hivemq:
      rootFolder: /hivemq/
    limits:
      heap: 4G
  clickhouse:
    replication:
      label: has-clickhouse
    port:
      map: 8123
      export: false
    db:
      name: iotcore
  olapservice:
    logLevel: INFO
    replication:
      label: has-olap
      replicaCount: 1
    limits:
      heap: 4G
    external:
      # Будет ли развернут olapservice И clickhouse на стороннем хосте.
      # Если true, то отключает установку olapservice и clickhouse средствами Ansible.
      enable: false
      # Если установка olapservice на сторонний хост будет выполняться средствами ansible, то в какую директорию.
      installDir: /storage/iot
      # Внешний адрес стороннего хоста, по которому платформа будет подключаться к olapservice'у.
      # Параметр должен иметь схему ("http://" или "https://")
      host: "external.olapservice.address"
    port:
      map: 8023
      export: false
    rabbit:
      queue:
        # Идентификатор очереди для отправки событий из core в olapservice.
        save: olapservice-save-queue
      exchange:
        # Идентификатор топик-коллектора.
        events: eventlog-exchange
      routingKey:
        # Ключ маршрутизации для сообщений сохранения событий в сервис хранения логов событий.
        save: events.save
      # Количество консьюмеров на стороне Olapservice.
      olapservice:
        # Данный параметр не может быть больше чем maxCount.
        consumersCount: 1
        # Максимальное количество одновременных консьюмеров очереди.
        consumersMaxCount: 1
        # Максимальное количество необработанных *пачек*, которые RabbitMQ доставляет одной реплике Olapservice до
        # получения подтверждений.
        # Документация: https://www.rabbitmq.com/docs/confirms#channel-qos-prefetch
        prefetchCount: 50
        # Ограничение на число *пачек*, обрабатываемых одновременно внутри одной реплики Olapservice.
        # Количество пачек может быть ниже, если долго нет новых сообщений (см. batchReceiveTimeout).
        # Фактическое количество сообщений зависит от core.batchSize:
        #   msgTotal <= core.batchSize * olapservice.batchSize
        # Например, если olapservice.batchSize=10, а Core отправил 20 пачек средним размером по 80 сообщений,
        #     то обработано будет 10*80=800 сообщений единовременно.
        batchSize: 10
        # Максимальное время ожидания от момента поступления первого сообщения в пачку до начала её обработки
        # в Olapservice.
        batchReceiveTimeout: 100ms
      core:
        # Максимальное количество сообщений в одной пачке, которую Core отправляет в Olapservice через RabbitMQ.
        # Фактический размер может быть меньше, если:
        #   - превышен размер пачки (см. параметр bufferLimit)
        #   - долго нет новых событий (см. параметр batchTimeout).
        # Не рекомендуется превышать qos * число реплик Olapservice.
        # Документация: https://docs.spring.io/spring-amqp/reference/amqp/sending-messages.html#template-batching
        batchSize: 100
        # Верхний предел суммарного размера пачки в байтах. При достижении этого размера накопление останавливается
        # и текущая пачка отправляется.
        # Расчёт основан на предположении ~1 КБ на сообщение при заданном prefetch (qos).
        bufferLimit: 102400
        # Максимальное время ожидания Core перед отправкой неполного батча, если в очередь не поступают новые сообщения.
        # Таймер сбрасывается при добавлении каждого нового сообщения, поэтому высокая задержка нежелательна.
        # Максимальное общее время задержки перед отправкой пачки в RabbitMQ = batchSize * batchTimeout.
        batchTimeout: 10ms
  captcha:
    enable: true
    replication:
      label: has-captcha
    port:
      map: 8088
      export: false
    caseSensitive: true
    allowedSizes:
      - "312x45"
      - "270x40"
    instance: "captcha:8088"
    proportion: 100
  zscaptcha:
    enable: false
    replication:
      label: has-captcha
    port:
      map: 8089
      export: false
    caseSensitive: true
    instance: "zs-captcha:8089"
    proportion: 0
  authorization:
    # Развертывание окружения без auth server, полезно для разработки auth server.
    enable: true
    replication:
      label: has-authorization
    limits:
      heap: 4G
    external:
      host: "external.authorization.address"
    port:
      map: 8091
      export: false
      ssl:
        map: 8093
        export: false
    db:
      name: iot-authorization-server
    jconsole:
      enable: false
      port: 32003
      # Необходимо указать адрес хоста, куда будет подключаться jconsole-клиент.
      # При развертывании докера - здесь указывается адреса хоста, где работает докер.
      host: "10.20.30.40"
    email:
      blacklist:
        # "0 * * * * ?" раз в минуту
        # "0 ${random.int[60]} ${random.int[1,5]} 1 * ?" раз в неделю
        cron: "0 ${random.int[60]} ${random.int[1,5]} 1 * ?"
    swagger:
      enable: false
    rabbit:
      voiceAuthDataQueues:
        toAuthServer:
          name: platform-auth-queue
        fromAuthServer:
          name: auth-platform-queue
      authReceiveAndReply:
        name: auth-receive-and-reply
        timeout: 30s
      # Количество консьюмеров на стороне платформы
      platformConsumers:
        # Данный параметр не может быть больше чем maxCount.
        count: 16
        # Максимальное количество одновременных консьюмеров очереди.
        maxCount: 16
      # Настройки сервиса уведомлений
      notification:
        # Количество консюмеров
        сount: 1
        #Максимальное количество консюмеров
        maxCount: 5
        #Наименования обменика
        exchange: notification-exchange
        #Ключ маршртута для уведомлений
        envelopeRoutingKey: notification
        #Ключ маршртута событий входа/выхода
        userEventRoutingKey: userevent
  guard:
    logLevel: INFO
    external:
      # Будет ли развернут guard на стороннем хосте.
      enable: false
      # Если установка guard на сторонний хост будет выполняться средствами ansible, то в какую директорию.
      installDir: /storage/iot
    replication:
      replicaCount: 1
      label: has-guard
    limits:
      heap: 4G
    port:
      map: 8101
      export: false
      ssl:
        map: 8103
        export: false
    db:
      name: iot-guard
    jconsole:
      enable: false
      port: 32005
      # Необходимо указать адрес хоста, куда будет подключаться jconsole-клиент.
      # При развертывании докера - здесь указывается адреса хоста, где работает докер.
      host: "10.20.30.40"
    swagger:
      enable: false
    rabbit:
      queue:
        coreReceive: core-receive-from-guard-queue
        coreReceiveAndReply: core-receive-from-guard-and-reply-queue
        guardReceive: guard-receive-from-core-queue
        guardReceiveAndReply: guard-receive-from-core-and-reply-queue
      consumers:
        # Количество одновременных консьюмеров очереди. Данный параметр не может быть больше чем maxCount.
        count: 1
        # Максимальное количество одновременных консьюмеров очереди.
        maxCount: 1
      replyTimeout: 30s
  payment:
    enable: true
    # ApiKey используется для доступа к АПИ платежного сервиса.
    apiKey: "CHANGE_ME"
    replication:
      label: has-payment
    limits:
      heap: 4G
    port:
      map: 9091
      export: false
      ssl:
        map: 9093
        # Если експорт false, то запросы будут проксироваться через Nginx. Для тестирования флаг можно включать.
        # Если флаг true, то запросы должны ходить на прямую в payment service
        export: false
    internal:
      # Максимальный временной период, через который будет повторятся запрос статуса платежа на платежный сервис.
      orderCheckTimePeriodMax: "30m"
      # Максимальное время, через которое сервис перестает опрашивать ордер.
      orderCheckTimeTotal: "24h"
      # Промежуток времени, через который повторяется отправка сообщения на платформу об успешной оплате,
      # чтобы платформа создала подписку. Повторная отправка отменяется если платформа прислала сообщение о создании
      # подписки или если количество попыток передать сообщение превысило параметр checkSubscriptionCreatedMaxAttempts
      checkSubscriptionCreatedPeriodTime: "5m"
      # Количество попыток передать платформе сообщение об успешной оплате.
      checkSubscriptionCreatedMaxAttempts: 10
    db:
      name: iot-payment-server
    jconsole:
      enable: false
      port: 32004
      # Необходимо указать адрес хоста, куда будет подключаться jconsole-клиент.
      # При развертывании докера - здесь указывается адреса хоста, где работает докер.
      host: "10.20.30.40"
    swagger:
      enable: false
    paySystem:
      # Необходимо указать ендпоинт на стороне IoT-Core куда будут переадресовываться запросы с ЮКассы.
      # МП приложения могут сами распозновать , что вебвью с ЮКассой закрыта, и кидать необходимый запрос на Iot-core
      # и переходить на нужный экран. Веб так не умеет, поэтому создан этот параметр. Когда веб поддержит покупку
      # тарифов, нужно будет уточнить на какую именно страницу нужно делать редирект.
      redirectUrlAfterPay: "https://eltexhome.ru"
      yooKassa:
        url: "https://api.yookassa.ru/v3"
        # Идентификатор магазина.
        shopId: ""
        secretKey: ""
        # Cписок доступных IP адресов запросов от Юкассы. Взято из официально документации.
        # https://yookassa.ru/developers/using-api/webhooks#ip
        availableHosts:
          - "185.71.76.0/27"
          - "185.71.77.0/27"
          - "77.75.153.0/25"
          - "77.75.156.11"
          - "77.75.156.35"
          - "77.75.154.128/25"
          - "2a02:5180::/32"
    rabbit:
      queue:
        # Очередь для приема сообщений от платформы.
        paymentReceive: "paymentReceive"
        # Очередь для приема сообщений от платформы и синхронного ответа во временную очередь.
        paymentReceiveAndReply: "paymentReceiveAndReply"
        # Время ожидания синхронного ответа от PaymentServer на сообщение, отправленное в очередь
        # paymentReceiveAndReply
        paymentReceiveAndReplyQueueTimeOut: "30s"
        # Очередь для отправки сообщений на платформу.
        platformReceive: "platformReceive"
      consumers:
        # Количество одновременных консьюмеров в Iot-Core для очереди platformReceive.
        # Данный параметр не может быть больше чем maxCount.
        coreCount: 1
        # Максимальное количество одновременных консьюмеров в Iot-Core для очереди platformReceive.
        coreMaxCount: 1
        # Количество одновременных консьюмеров в Iot-Pqyment-Server для очереди paymentReceiveAndReply.
        paymentCount: 10
        # Максимальное количество одновременных консьюмеров в Iot-Pqyment-Server для очереди paymentReceiveAndReply.
        paymentMaxCount: 20
  core:
    external:
      # Будет ли развернут core на стороннем хосте.
      enable: false
      # Если установка core на сторонний хост будет выполняться средствами ansible, то в какую директорию.
      installDir: /storage/iot
    replication:
      replicaCount: 1
      label: has-core
    limits:
      heap: 4G
    port:
      map: 8071
      export: false
      ssl:
        map: 8073
        export: false
    db:
      name: iot-core
      # Имена устаревших БД в MongoDB, используемые платформой.
      deprecated:
        fs:
          name: iot-fs
        licenses:
          name: iot-licenses
        events:
          name: iot-events
    jconsole:
      enable: false
      port: 32001
      # Необходимо указать адрес хоста, куда будет подключаться jconsole-клиент.
      # При развертывании докера - здесь указывается адреса хоста, где работает докер.
      host: "10.20.30.40"
    swagger:
      enable: false
    broker:
      # Нужно ли платформе пытаться подключиться к MQTT Broker.
      enable: true
      useShareSubscriptions: false
      threadPools:
        main:
          size: 16
    olapservice:
      # Нужно ли платформе пытаться подключиться к OlapService.
      enable: true
    mjollnir:
      # URL для Mjollnir.
      url: "http://smart.eltex-co.ru:8078/api/v1"
    slgate:
      instances:
        - slgate:4443
      ignoreServerCertCheck: false
    video:
      evi:
        ignoreServerCertCheck: false
      # Api-key для валидации ивентов со стороны EVI Cloud перед его обработкой
        eventApiKey: "CHANGE_ME"
      # Параметры WebRTC, которые необходимы камере для формирования своих ICE-кандидатов.
      webrtc:
        # Параметры STUN-сервера.
        stun:
          # URL STUN-серверов.
          urls:
            - "stun.example1.com:3478"
            - "stun.example2.com:3478"
        # Параметры TURN-сервера.
        turn:
          # Параметры TURN:SFU
          sfu:
            # Принудительное включение
            force: false
            # Таймаут на ожидание ивента от EVI о начале webrtc-сессии между камерой и TURN:SFU
            eventTimeout: 10s
        # Параметры P2P
        p2p:
          # Таймаут на ожидание SDP-answer от камеры
          sdpAnswerTimeout: 60s
        # Время ожидания проверки камерой типа своего NAT
        checkCameraNatTypeTimeout: 10s
        # Время выполнения ping к host candidate клиента
        pingHostCandidateTimeout: 10s
    rabbit:
      events:
        queue:
          name: platform-rpc-event-queue
      notification:
        exchange: notification-exchange
        envelopeRoutingKey: notification
        userEventRoutingKey: userEvent
        count: 1
        maxCount: 1
    # Сервис управления голосом Cloud ASR https://intdocs.eltex.loc/pages/viewpage.action?pageId=125740527
    voice:
      # Адрес Cloud ASR, для подключения платформы.
      host: "127.0.0.1"
      port: 443
      # Ключ по которому Cloud ASR будет отправлять запрос на генерацию новой пары токенов для колонки.
      # TODO будет удален в рамках #397994
      apiKey: "CHANGE_ME"
      # Параметры клиентского сертификата, используемого для авторизованного подключения платформы к Cloud ASR.
      clientKeyStoreParams:
        # Включить передачу клиентского сертификата. Следует переводить в значение true для продуктовой среды.
        enable: false
        # Путь до файла с форматом PKCS12 (*.p12), содержащего клиентский сертификат.
        path: "/etc/ssl/private/asr_client.p12"
        # Пароль от клиентского сертификата (*.p12).
        password: ""
      # Игнорировать ошибки при проверке сертификата сервера (полезно при работе с самоподписанными сертификатами)
      ignoreServerCertCheck: true
  web:
    # Развертывание окружения без WEB, полезно для разработки web.
    enable: true
    replication:
      label: has-web
  hazelcast:
    clusterName: iot-core
    instanceName: iot-core-hazelcast-instance
    replication:
      label: has-hazelcast
    external:
      port:
        map: 5701
        export: false
  rabbitmq:
    logLevel: info
    replication:
      label: has-rabbitmq
    persistence:
      enabled: true
    admin:
      user: guest
      password: guest
      port:
        map: 15672
        export: false
    cluster:
      # Кука безопасности, для взаимодействя нод в кластере
      cookie: AHSUSTCTPUGYENLLYOLB
      # Количество попыток формирования кластера
      discoveryRetryLimit: 120
      # Интервал повторной попытки формирования кластера (в секундах)
      discoveryRetryInterval: 1
      # Время ожидания восстановления консистентности базы mnesia (в секундах)
      mnesiaTableLoadingRetryTimeout: 10
      # Количество попыток восстановления консистентности базы mnesia
      mnesiaTableLoadingRetryLimit: 10
      # Метка для нод воркеров в кластере
      label: rabbit-cluster-node
    port:
      map: 5672
      export: false
  zwayproxy:
    logLevel: INFO
    external:
      enable: false
      # Если установка zwayproxy на сторонний хост будет выполняться средствами ansible, то в какую директорию.
      installDir: /storage/iot
    replication:
      replicaCount: 2
      label: has-zwayproxy
    limits:
      heap: 4G
    port:
      map: 8070
      export: true
    sslPort:
      map: 8072
      export: true
    rabbit:
      queue:
        # Идентификатор очереди для отправки сообщений из прокси в платформу.
        platform: zway-proxy-platform
      exchange:
        # Идентификатор топик-коллектора.
        proxy: zway-proxy-topic-exchange
      # Количество консьюмеров на стороне платформы
      platformConsumers:
        # Данный параметр не может быть больше чем maxCount.
        count: 16
        # Максимальное количество одновременных консьюмеров очереди.
        maxCount: 16
      # Количество консьюмеров на стороне zwayProxy service
      proxyConsumers:
        # Количество одновременных консьюмеров очереди. Данный параметр не может быть больше чем maxCount.
        count: 1
        # Максимальное количество одновременных консьюмеров очереди.
        maxCount: 1
  wsproxy:
    logLevel: INFO
    maxConnections: 25000
    external:
      enable: false
      # Если установка wsproxy на сторонний хост будет выполняться средствами ansible, то в какую директорию.
      installDir: /storage/iot
      # Адрес хоста куда nginx будет проксировать запросы.
      host: "1.2.3.4"
      port: 8075
    replication:
      replicaCount: 2
      label: has-wsproxy
    limits:
      heap: 4G
    port:
      map: 8075
      export: true
    rabbit:
      queue:
        # Идентификатор очереди для отправки сообщений из прокси в платформу.
        platform: ws-proxy-platform
      exchange:
        # Идентификатор топик-коллектора.
        proxy: ws-proxy-topic-exchange
      # Количество консьюмеров на стороне платформы
      platformConsumers:
        # Данный параметр не может быть больше чем maxCount.
        count: 16
        # Максимальное количество одновременных консьюмеров очереди.
        maxCount: 16
      # Количество консьюмеров на стороне wsProxy service
      proxyConsumers:
        # Количество одновременных консьюмеров очереди. Данный параметр не может быть больше чем maxCount.
        count: 16
        # Максимальное количество одновременных консьюмеров очереди.
        maxCount: 16
  # Параметры установки сервисов мониторинга (Prometheus + Grafana) - только для режима compose.
  monitoring:
    external:
      # Будет ли развернут monitoring на стороннем хосте.
      enable: true
      # Нужно ли устанавливать monitoring на сторонний хост средствами ansible.
      install: false
      # Если установка monitoring на сторонний хост будет выполняться средствами ansible, то в какую директорию.
      installDir: /storage/iot
    mongodbExporter:
      replication:
        label: has-mongodb-exporter
      enable: true
      port:
        map: 9216
        export: false
    nginxExporter:
      replication:
        label: has-nginx-exporter
      enable: true
      port:
        map: 9113
        export: false
    prometheus:
      port:
        map: 9090
        export: false
      # Период опроса сервисов со стороны Prometheus в секундах. Небольшие значения (менее десятков секунд) значительно
      # увеличат нагрузку на сеть.
      # При изменении параметра рекомендуется поменять переменную grafana.scrapeInterval на значение не ниже указанного
      # для Prometheus, чтобы не терять метрики.
      scrapeInterval: 60
    grafana:
      port:
        map: 3000
      # Период опроса Prometheus со стороны Grafana в секундах.
      scrapeInterval: 60
  # Параметры установки сервисов Peeper (мониторинга).
  # В swarm-режиме Peeper запускается также как платформа через docker-swarm на том же кластере(связанные хосты),
  # но в другом стеке (совокупность сервисов и контейнеров из которых состоит приложение).
  # Т.к ansible-playbook создает кластер, то было принято решение чтобы ansible-playbook и расставлял все лейблы на
  # ноды, но при этом запуск Peeper осуществляется вручную, а не по ansible-playbook, потому что это стороннее
  # программное обеспечение напрямую не относящееся к ELIS.
  peeper:
    agent:
      replication:
        label: has-peeper-agent
    provision:
      replication:
        label: has-peeper-provision
    telegraf:
      replication:
        label: has-peeper-telegraf
  notification:
    enable: true
    logLevel: INFO
    replication:
      label: has-notification
    limits:
      heap: 4G
    jconsole:
      enable: false
      port: 32002
      # Необходимо указать адрес хоста, куда будет подключаться jconsole-клиент.
      # При развертывании докера - здесь указывается адреса хоста, где работает докер.
      host: "10.20.30.40"
    port:
      export: false
      map: 9095
    rabbit:
      exchange: notification-exchange
      envelopeRoutingKey: notification
      userEventRoutingKey: userevent
    retry:
      maxAttempts: 3
      backoff: 120000
    vault:
      uri: https://127.0.0.1:8200
      token: RootToken
      ssl:
        useTrustStore: false
        trustStore: file:///etc/vault.jks
        trustStoreType: jks
        trustStorePassword: vault0
      rootPath: credentials
    push:
      fcm:
        # Период между отправкой пушей, для достижения ограничения частоты отправки пушей.
        delay: 250ms
  minio:
    port:
      export: false
      map: 9000
    external:
      enable: false
      url: http://minio:9000
      accessKey: minioadmin
      secretKey: minioadmin
    # Список предопределенных корзин, создаваемых до запуска экземпяра Minio
    buckets:
      - iot
      - critical-iot
    # Список корзин для бэкапа
    backups:
      - critical-iot
    console:
      port: 9001
    replication:
      label: has-minio
slgate:
  db:
    name: "activator"
    user: "activator"
    password: "activator"
    port:
      map: 5432
      export: false
  vpn:
    port:
      map: 1194
    protocol: udp
    maxClients: 1024
  easyrsa:
    req:
      country: "RU"
      province: "Novosibirsk"
      city: "Novosibirsk"
      organization: "Eltex"
      organizationUnit: "EMS"
      email: "eltex@eltex-co.ru"
  activator:
    port:
      map: 8899
      export: false
  proxy:
    scheme: "https://"
    useClientCert: false
    clientCertPassword: "CHANGE_ME"
    port:
      map: 4443

# Параметры сервисов ELK (для docker-compose), сгруппированные по именам.
# 'port.map' - номер порта сервиса в сети хоста.
# 'port.export' - нужно ли выполнять маппинг порта из контейнера в сеть хоста.
elk:
  elasticsearch:
    rest:
      port:
        map: 9200
    nodes:
      port:
        map: 9300
  logstash:
    port:
      map: 5001
    api:
      port:
        map: 9600
  kibana:
    port:
      map: 5601
  fluentBit:
    port:
      map: 24224
    # Индексы, создаваемые в elasticsearch со стороны fluentBit для наших Java-микросервисов
    javaTargets:
      - core
      - authorization
      - notification
      - payment
      - zwayproxy
      - wsproxy
      - mqttbroker
      - olapservice

# Параметры для сервисов видеонаблюдения EVI.
evi:
  watcher:
    sslPort:
      map: 5085
      export: true
    port:
      map: 5084
      export: true
    wsPort:
      map: 5083
      export: true
    dbName: watcher
  cloudControl:
    port:
      map: 10000
      export: true
    dbName: control
  cloudRat:
    port:
      map: 19199
      export: true
    sslPort:
      map: 10456
      export: true
    dbName: rat
  db:
    root: admin
    rootPassword: admin
    eviUser: eviuser
    eviUserPassword: eviuser
    port:
      map: 5432
      export: true

Описание основных параметров платформы умного дома в файле service_parameters.yml:

ПараметрЗначение по умолчаниюТребуемое значениеОписание
iot.captcha.caseSensitivetruefalseВключение чувствительности к регистру captcha при регистрации.
iot.broker.external.port.map88838883Порт для подключения Wi-Fi MQTT устройств к платформе умного дома.
iot.rabbitmq.admin.port.exporttruefalseВключение проброса порта панели администратора RabbitMQ (HTTP).
iot.rabbitmq.admin.sslPort.exporttruefalseВключение проброса порта панели администратора RabbitMQ (HTTPS).
iot.zwayproxy.port.map80708070

Порт для подключения Z-Wave-контроллера (незащищенное соединение).

Обязательно должно совпадать с iot.core.ctlGate.port из файла default.yml

iot.zwayproxy.sslPort.map80728072

Порт для подключения Z-Wave-контроллера (незащищенное соединение).

Обязательно должно совпадать с iot.core.ctlGate.sslPort из файла default.yml

iot.wsproxy.port.map80758075Порт для установления WebSocket-соединения с мобильными приложениями и веб-интерфейсом с целью передачи событий от платформы умного дома в реальном времени.




4. Сконфигурируйте параметры для работы платформы умного дома в файле /etc/ansible-iot/latest/templates/iot/authorization-server.yml.j2.

sudo nano /etc/ansible-iot/latest/templates/iot/authorization-server.yml.j2

Структура файла /etc/ansible-iot/latest/templates/iot/authorization-server.yml.j2:

authorization-server.yml.j2
# Доменное имя сервера, на котором развернута платформа
  name: "{{ iot.serverName }}"
  # Дефолтный язык отображения событий и сообщений
  language: "ru"
  port: {{ iot.authorization.port.map }}
  ssl:
    port: {{ iot.authorization.port.ssl.map }}
    key: "/etc/ssl/private/authorization-server.key"
    crt: "/etc/ssl/certs/authorization-server.crt"
  ui:
    # Доменное имя сервера, на котором развернут UI (WEB)
    name: "{{ iot.serverName }}"
    # Порты UI нужны для формирования на платформе ссылок, которые пользователь сможет открыть через UI.
    port: {{ iot.web.httpPort }}
    ssl:
      port: {{ iot.web.httpsPort }}
  # Параметры для формирования ссылок к UI(WEB) и API
  links:
    # Использовать схему https:// при формировании ссылок к UI
    useHttpsForUi: {{ 'true' if iot.web.useHttpsByDefault else 'false' }}
  # Ссылка на политику конфиденциальности
  privacyPolicyUrl: "{{ iot.privacyPolicyUrl }}"
  # Конфигурация tomcat
  tomcat:
    # Время простоя соединения
    connection-timeout: 2m
    max-connections: 25000
    max-http-form-post-size: 200000B
    # Конфигурация потоков
    threads:
      # Минимальное количество потоков
      min-spare: 32
      # Максимальное количество потоков
      max: 512
      # Максимальный размер очереди задач для потоков
      max-queue-capacity: 32768

services:
  # Параметры внутренних сервисов (компонентов) платформы.
  internal:
    loginInfo:
      # Время жизни разлогиненных записей loginInfo, с даты выхода из учетной записи
      ttl: 180d
      # Максимально допустимый интервал времени отсутствия активности со стороны пользователя
      # по истечении которого неактивные loginInfo (и привязанные к ним авторизации) автоматически разлогиниваются
      activityTimeLimit: 180d
    user:
      # Максимально допустимый интервал времени отсутствия активности со стороны пользователя
      # перед его деактивацией
      allowedInactivePeriod: 180d
      selfRegistration:
        allow: {{ 'true' if iot.authorization.selfRegistration.allow else 'false' }}
        allowDemo: {{ 'true' if iot.authorization.selfRegistration.allowDemo else 'false' }}
    email:
      blacklist:
        cron: "{{ iot.authorization.email.blacklist.cron }}"
    voice:
      # Время до окончания действия токена, за которое ASR должен начать запрашивать новый токен авторизации.
      timeToStartRefreshToken: 10m
      refreshTokenTimeToLive: 30d

  # Параметры для подключения к внешним сервисам, а также параметры внутренних сервисов (компонентов) платформы,
  # обеспечивающих работу с внешними сервисами.
  external:
    rabbitmq:
      # Должен ли сервис использовать тип очередей Quorum. Если развернут кластер RabbitMq, то в нем возможны только
      # очереди типа Quorum.
      useQuorumQueues: {{ 'true' if iot.swarm.enabled else 'false' }}
    captcha:
      # Список инстансов капчи (Libre CAPTCHA, Zero Storage Captcha)
      instances: {{ captcha_instances | join(', ') }}
      proportions: {{ captcha_proportions | join(', ') }}
      level: "{{ iot.authorization.captchaLevel }}"
    hazelcast:
      instanceName: "{{ iot.hazelcast.instanceName }}"
      clusterName: "{{ iot.hazelcast.clusterName }}"
      clientNetworking:
        # Пример: "127.0.0.1:5701, 127.0.0.1:5702"
        addresses: "hazelcast:5701"
    rpc:
      rabbit:
        authReceiveAndReply:
          name: {{ iot.authorization.rabbit.authReceiveAndReply.name }}
    core:
      voice:
        rabbit:
          fromPlatform:
            name: {{ iot.authorization.rabbit.voiceAuthDataQueues.toAuthServer.name }}
          toPlatform:
            name: {{ iot.authorization.rabbit.voiceAuthDataQueues.fromAuthServer.name }}
      events:
        rabbit:
          queue:
            name: {{ iot.core.rabbit.events.queue.name }}
    wsproxy:
      manager:
        replicaCheckPeriod: 5s
        replicaDeadPeriod: 15s
        connectAliveWaitPeriod: 15s
      rabbit:
        queue:
          # Идентификатор очереди для отправки сообщений из прокси в платформу.
          platform: {{ iot.wsproxy.rabbit.queue.platform }}
        exchange:
          # Идентификатор топик-коллектора.
          proxy: {{ iot.wsproxy.rabbit.exchange.proxy }}
        consumers:
          # Количество одновременных консьюмеров очереди. Данный параметр не может быть больше чем maxCount.
          count: {{ iot.wsproxy.rabbit.platformConsumers.count }}
          # Максимальное количество одновременных консьюмеров очереди.
          maxCount: {{ iot.wsproxy.rabbit.platformConsumers.maxCount }}
    notification:
      rabbitmq:
        exchange: {{ iot.authorization.rabbit.notification.exchange }}
        envelopeRoutingKey: {{ iot.authorization.rabbit.notification.envelopeRoutingKey }}
        userEventRoutingKey: {{ iot.authorization.rabbit.notification.userEventRoutingKey }}
db:
  uri: "{{ mongodb_uri }}"
  authorization:
    database: "{{ iot.authorization.db.name }}"
  # Используется для миграции, переносящей авторизационные сущности из БД core в БД authorization server
  core:
    database: "{{ iot.core.db.name }}"

spring:
  security:
    oauth2:
      # Время жизни access-токена, должно быть не менее 5 сек.
      # Также нужно учесть, что authorization server добавляет запас времени 60 секунд до того, как токен будет считаться
      # просроченным. Т.о. итоговое время жизни токена: accessTokenTimeToLive + 60 сек.
      accessTokenTimeToLive: 1h
      registration-parameters:
        apple:
          keyId: "{{ iot.authorization.clientRegistrations.apple.keyId }}"
          keyFile: "/etc/eltex-sc/apple-credentials/AuthKey_{keyId}.p8"
          teamId: "{{ iot.authorization.clientRegistrations.apple.teamId }}"
        yandex:
          avatarUrl: "https://avatars.yandex.net/get-yapic/{avatarId}/islands-50"
      client-parameters:
        web-client:
          type: WEB
          password: password
          clientAuthenticationMethod: client_secret_basic
          authorizationGrantTypes:
            - authorization_code
            - password
            - refresh_token
{% if iot.web.httpsPort != 443 %}
          redirectUri: "https://{{ iot.serverName }}:{{ iot.web.httpsPort }}/ng/login"
{% else %}
          redirectUri: "https://{{ iot.serverName }}/ng/login"
{% endif %}
          allowAdminLogin: true
          allowRevokeAll: true
          integration: false
        android-client:
          type: ANDROID
          password: password
          clientAuthenticationMethod: client_secret_basic
          authorizationGrantTypes:
            - authorization_code
            - password
            - refresh_token
          redirectUri: "https://eltex.iot.app/authorization"
          allowRevokeAll: true
          integration: false
        ios-client:
          type: IOS
          password: password
          clientAuthenticationMethod: client_secret_basic
          authorizationGrantTypes:
            - authorization_code
            - password
            - refresh_token
          scopes:
            - read
            - write
            - trust
          redirectUri: "https://eltex.iot.app/authorization"
          allowRevokeAll: true
          integration: false
{% if iot.authorization.skills.yandex.enabled %}
        {{ iot.authorization.skills.yandex.clientId }}:
          type: YANDEX
          password: "{{ iot.authorization.skills.yandex.password }}"
          clientAuthenticationMethod: client_secret_post
          authorizationGrantTypes:
            - authorization_code
            - refresh_token
          redirectUri: "https://social.yandex.net/broker/redirect"
          integration: true
{% endif %}
{% if iot.authorization.skills.sber.enabled %}
        {{ iot.authorization.skills.sber.clientId }}:
          type: SBER
          password: "{{ iot.authorization.skills.sber.password }}"
          clientAuthenticationMethod: client_secret_post
          authorizationGrantTypes:
            - authorization_code
            - refresh_token
          redirectUri: "https://gateway.iot.sberdevices.ru/gateway/v1/binder/backward"
          integration: true
{% endif %}
{% if iot.authorization.skills.marusya.enabled %}
        {{ iot.authorization.skills.marusya.clientId }}:
          type: MARUSYA
          password: "{{ iot.authorization.skills.marusya.password }}"
          clientAuthenticationMethod: client_secret_post
          authorizationGrantTypes:
            - authorization_code
            - refresh_token
          redirectUri: "https://vc.go.mail.ru/smarthouse/{{ iot.authorization.skills.marusya.appId }}/callback"
          integration: true
{% endif %}
{% if iot.authorization.selfRegistration.allowSocialNetworks %}
      client:
        provider:
{% if iot.authorization.clientRegistrations.microsoft.enable %}
          microsoft:
            authorization-uri: "https://login.microsoftonline.com/consumers/oauth2/v2.0/authorize?response_mode=form_post"
            token-uri: "https://login.microsoftonline.com/consumers/oauth2/v2.0/token"
            jwk-set-uri: "https://login.microsoftonline.com/consumers/discovery/v2.0/keys"
            user-info-uri: "https://graph.microsoft.com/oidc/userinfo"
            user-info-authentication-method: "header"
            user-name-attribute: "sub"
{% endif %}
{% if iot.authorization.clientRegistrations.apple.enable %}
          apple:
            authorization-uri: "https://appleid.apple.com/auth/authorize?response_mode=form_post"
            token-uri: "https://appleid.apple.com/auth/token"
            jwk-set-uri: "https://appleid.apple.com/auth/keys"
            issuer-uri: "https://appleid.apple.com"
            user-info-uri: "not_provided"
            user-name-attribute: "sub"
{% endif %}
{% if iot.authorization.clientRegistrations.yandex.enable %}
          yandex:
            authorization-uri: "https://oauth.yandex.ru/authorize"
            token-uri: "https://oauth.yandex.ru/token"
            user-info-uri: "https://login.yandex.ru/info"
            user-info-authentication-method: "header"
            user-name-attribute: "id"
{% endif %}
{% if iot.authorization.clientRegistrations.vk.enable %}
          vk:
            authorization-uri: "https://oauth.vk.ru/authorize"
            token-uri: "https://oauth.vk.ru/access_token"
            user-info-uri: "https://api.vk.ru/method/users.get?v=5.131&fields=bdate,photo_50"
            user-info-authentication-method: "header"
            user-name-attribute: "id"
{% endif %}
{% if iot.authorization.clientRegistrations.mailRu.enable %}
          mail-ru:
            authorization-uri: "https://oauth.mail.ru/login"
            token-uri: "https://oauth.mail.ru/token"
            user-info-uri: "https://oauth.mail.ru/userinfo"
            user-info-authentication-method: "query"
            user-name-attribute: "id"
{% endif %}
        registration:
{% if iot.authorization.clientRegistrations.google.enable %}
          google:
            client-id: "{{ iot.authorization.clientRegistrations.google.clientId }}"
            client-secret: "{{ iot.authorization.clientRegistrations.google.clientSecret }}"
{% endif %}
{% if iot.authorization.clientRegistrations.microsoft.enable %}
          microsoft:
            provider: microsoft
            client-name: Microsoft
            client-id: "{{ iot.authorization.clientRegistrations.microsoft.clientId }}"
            client-secret: "{{ iot.authorization.clientRegistrations.microsoft.clientSecret }}"
            client-authentication-method: client_secret_post
            authorization-grant-type: authorization_code
            redirect-uri: "{baseUrl}/v1/{action}/oauth2/code/{registrationId}"
            scope:
              - openid
              - profile
              - email
{% endif %}
{% if iot.authorization.clientRegistrations.apple.enable %}
          apple:
            provider: apple
            client-name: Apple
            client-id: "{{ iot.authorization.clientRegistrations.apple.clientId }}"
            client-secret: "autogenerated"
            client-authentication-method: client_secret_post
            authorization-grant-type: authorization_code
            redirect-uri: "{baseUrl}/v1/{action}/oauth2/code/{registrationId}"
            scope:
              - openid
              - name
              - email
{% endif %}
{% if iot.authorization.clientRegistrations.yandex.enable %}
          yandex:
            provider: yandex
            client-name: Yandex
            client-id: "{{ iot.authorization.clientRegistrations.yandex.clientId }}"
            client-secret: "{{ iot.authorization.clientRegistrations.yandex.clientSecret }}"
            client-authentication-method: client_secret_basic
            authorization-grant-type: authorization_code
            redirect-uri: "{baseUrl}/v1/{action}/oauth2/code/{registrationId}"
            scope:
              - login:avatar
              - login:birthday
              - login:email
              - login:info
              - login:default_phone
{% endif %}
{% if iot.authorization.clientRegistrations.vk.enable %}
          vk:
            provider: vk
            client-name: VK
            client-id: "{{ iot.authorization.clientRegistrations.vk.clientId }}"
            client-secret: "{{ iot.authorization.clientRegistrations.vk.clientSecret }}"
            client-authentication-method: client_secret_post
            authorization-grant-type: authorization_code
            redirect-uri: "{baseUrl}/v1/{action}/oauth2/code/{registrationId}"
            scope:
              - email
              - phone_number
{% endif %}
{% if iot.authorization.clientRegistrations.mailRu.enable %}
          mail-ru:
            provider: mail-ru
            client-name: Mail.ru
            client-id: "{{ iot.authorization.clientRegistrations.mailRu.clientId }}"
            client-secret: "{{ iot.authorization.clientRegistrations.mailRu.clientSecret }}"
            client-authentication-method: client_secret_basic
            authorization-grant-type: authorization_code
            redirect-uri: "{baseUrl}/v1/{action}/oauth2/code/{registrationId}"
            scope:
              - userinfo
{% endif %}
{% endif %}
  mail:
    host: "{{ 'false' if iot.useNotification else iot.mail.smtp.host }}"
    port: {{ iot.mail.smtp.port }}
    username: "{{ iot.mail.smtp.submitter }}"
    password: "{{ iot.mail.smtp.password }}"
    properties:
      mail:
        from: "{{ iot.mail.smtp.submitter }}"
        personal: "{{ iot.mail.smtp.senderPrefix }}"
        smtp:
          auth: true
{% if iot.mail.smtp.protection == "starttls" %}
          starttls:
            enable: true
            required: true
{% elif iot.mail.smtp.protection == "ssl" %}
          ssl:
            enable: true
{% endif %}
  rabbitmq:
    host: rabbitmq
    port: 5672

springdoc:
  swagger-ui:
    # Включение и отключение swagger.
    enabled: {{ 'true' if iot.authorization.swagger.enable else 'false' }}

logging:
  config: "{{ iot.logbackConfig }}"
  logback:
    dir: "/var/log/elis"
{% if elk.enable %}
  logstash:
    host: "{{ elk.serverName }}"
    port: {{ elk.logstash.port.map }}
{% endif %}
  level:
    root: {{ iot.authorization.logLevel }}
    org.springframework: WARN
    org.springframework.cache: WARN
    org.springframework.data: WARN
    org.springframework.web: WARN
    _org.springframework.web: WARN
    org.springframework.security: WARN
    org.springframework.security.oauth2: WARN
    org.springdoc: WARN
    org.mongodb: WARN
    org.apache.http: WARN
    org.thymeleaf: WARN
    io.swagger: WARN
    io.mongock: INFO
    io.micrometer: WARN
    com.hazelcast: WARN

Описание основных параметров платформы умного дома в файле authorization-server.yml.j2:

ПараметрЗначение по умолчаниюТребуемое значениеОписание
services.internal.loginInfo.ttl180d10000dВремя жизни записей loginInfo в БД после выхода пользователя из учетной записи.
services.internal.loginInfo.activityTimeLimit180d10000d

Максимально допустимый интервал времени отсутствия активности со стороны пользователя, по истечении которого происходит принудительная деавторизация.

services.internal.loginInfo.allowedInactivePeriod180d10000d

Максимально допустимый интервал времени отсутствия активности со стороны пользователя перед его деактивацией.

При повторном входе в аккаунт после деактивации потребуется подтвердить адрес электронной почты.




5. Сконфигурируйте параметры для работы контейнеров платформы умного дома в файле /etc/ansible-iot/latest/templates/iot/docker-swarm/swarm_config.yml.j2.

sudo nano /etc/ansible-iot/latest/templates/iot/docker-swarm/swarm_config.yml.j2

Структура файла /etc/ansible-iot/latest/templates/iot/docker-swarm/swarm_config.yml.j2:

swarm_config.yml.j2
services:

# -------------------------------------------------------- Db --------------------------------------------------------
{% if not iot.mongodb.external.enable %}
  mongodb:
    image: "{{ docker_services_map.mongodb.image }}"
    deploy:
      replicas: 1
      placement:
        constraints:
          - node.labels.{{ iot.mongodb.replication.label }} == yes
    healthcheck:
      test: ["CMD", "{{ mongosh }}", "--eval", "'db.runCommand(\"ping\").ok'", "--quiet"]
      interval: 30s
      timeout: 10s
      retries: 5
      start_period: 20s
    environment:
      - TZ={{ timezone.stdout }}
      - DISK_USAGE_THRESHOLD_WARN={{ iot.diskUsage.warnThreshold }}
      - DISK_USAGE_THRESHOLD_CRITICAL={{ iot.diskUsage.criticalThreshold }}
    volumes:
      - "{{ install_dir }}/mongodb/data/db:/data/db/"
      - "{{ install_dir }}/mongodb/mongobackups:/var/backups/mongobackups"
      - "{{ install_dir }}/mongodb/dictionaries:/var/dictionaries"
{% if iot.mongodb.port.export %}
    ports:
      - {{ iot.mongodb.port.map }}:27017
{% endif %}
{% if elk.enable %}
    logging:
      driver: "fluentd"
      options:
        fluentd-address: {{ elk.serverName  }}:{{ elk.fluentBit.port.map }}
        tag: iot.mongodb
{% endif %}
{% endif %}

  # ------------------------------------------------------ Minio ------------------------------------------------------
{% if not iot.minio.external.enable %}
  minio:
    image: "{{ docker_services_map.minio.image }}"
{% set iot_minio_hostname = 'minio'~('{{.Task.Slot}}' if ( groups['minio'] | length ) > 1 else '') %}
    hostname: {{ iot_minio_hostname }}
    deploy:
      replicas: {{ groups['minio'] | length }}
      placement:
        constraints:
          - node.labels.{{ iot.minio.replication.label }} == yes
        max_replicas_per_node: 1
    healthcheck:
      test: [ "CMD", "curl", "-f", "http://localhost:9000/minio/health/live" ]
      interval: 30s
      timeout: 20s
      retries: 3
    command:
{% set iot_minio_ellipsis = ('{1...' ~ (groups['minio'] | length) ~ '}' if (groups['minio'] | length) > 1 else '') %}
      - server
      - -quiet
      - --anonymous
      - --json
{% if (groups['minio'] | length) > 1 %}
      - http://minio{{ iot_minio_ellipsis }}:9000/data
{% else %}
      - /data
{% endif %}
    environment:
      - TZ={{ timezone.stdout }}
      - DISK_USAGE_THRESHOLD_WARN={{ iot.diskUsage.warnThreshold }}
      - DISK_USAGE_THRESHOLD_CRITICAL={{ iot.diskUsage.criticalThreshold }}
      - MINIO_PROMETHEUS_AUTH_TYPE=public
{% if iot.minio.root.user is defined %}
      - MINIO_ROOT_USER={{ iot.minio.root.user }}
{% endif %}
{% if iot.minio.root.pass is defined %}
      - MINIO_ROOT_PASSWORD={{ iot.minio.root.pass }}
{% endif %}
{% if iot.minio.console.port is defined %}
      - MINIO_CONSOLE_ADDRESS=:{{ iot.minio.console.port }}
{% endif %}
{% if minio_predefined_buckets is defined %}
      - PREDEFINED_BUCKETS={{ minio_predefined_buckets }}
{% endif %}
{% if minio_backup_buckets is defined %}
      - BACKUP_BUCKETS={{ minio_backup_buckets }}
{% endif %}
{% if iot.minio.port.export or iot.minio.console.port is defined %}
    ports:
{% if iot.minio.port.export %}
      - {{ iot.minio.port.map }}:9000
{% endif %}
{% if iot.minio.console.port is defined %}
      - {{ iot.minio.console.port }}:{{ iot.minio.console.port }}
{% endif %}
{% endif %}
    volumes:
      - "{{ minio_install_dir }}/data:/data"
      - "{{ minio_install_dir }}/miniobackups:/var/backups/miniobackups"
{% if elk.enable %}
    logging:
      driver: "fluentd"
      options:
        fluentd-address: {{ elk.serverName  }}:{{ elk.fluentBit.port.map }}
        tag: iot.minio
{% endif %}
{% endif %}


{% include "templates/iot/docker-swarm/include/rabbitmq.yml.j2" %}


# ----------------------------------------------------- Hazelcast ----------------------------------------------------
  hazelcast:
    image: "{{ docker_services_map.hazelcast.image }}"
    deploy:
      replicas: 1
      placement:
        constraints:
          - node.labels.{{ iot.hazelcast.replication.label }} == yes
    environment:
      - HZ_CLUSTERNAME={{ iot.hazelcast.clusterName }}
      - HZ_INSTANCENAME={{ iot.hazelcast.instanceName }}
{% if iot.hazelcast.external.port.export %}
    ports:
      - {{ iot.hazelcast.external.port.map }}:5701
{% endif %}
{% if elk.enable %}
    logging:
      driver: "fluentd"
      options:
        fluentd-address: {{ elk.serverName  }}:{{ elk.fluentBit.port.map }}
        tag: iot.hazelcast
{% endif %}


# -------------------------------------------------- Clickhouse --------------------------------------------------------
{% if not iot.olapservice.external.enable %}
  clickhouse:
    image: "{{ docker_services_map.clickhouse.image }}"
    deploy:
      replicas: 1
      placement:
        constraints:
          - node.labels.{{ iot.clickhouse.replication.label }} == yes
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:8123/ping"]
      interval: 30s
      timeout: 10s
      retries: 5
      start_period: 20s
    environment:
      - TZ={{ timezone.stdout }}
      - EVENT_LOG_DB_NAME={{ iot.clickhouse.db.name }}
      - DISK_USAGE_THRESHOLD_WARN={{ iot.diskUsage.warnThreshold }}
      - DISK_USAGE_THRESHOLD_CRITICAL={{ iot.diskUsage.criticalThreshold }}
    volumes:
      - "{{ install_dir }}/olapdb/conf/config.d/system_log_config.xml:/etc/clickhouse-server/config.d/system_log_config.xml"
      - "{{ install_dir }}/olapdb/conf/users.d/:/etc/clickhouse-server/users.d/"
      - "{{ install_dir }}/olapdb/data/:/var/lib/clickhouse/"
      - "{{ install_dir }}/olapdb/clickhouse-backup/config/config.yml:/etc/clickhouse-backup/config.yml"
      - "{{ install_dir }}/olapdb/clickhouse-backup/archives:/var/lib/clickhouse/archives"
      - "{{ install_dir }}/olapdb/var/log/clickhouse-server:/var/log/clickhouse-server"
{% if iot.clickhouse.port.export %}
    ports:
      - {{ iot.clickhouse.port.map }}:8123
{% endif %}
{% if elk.enable %}
    logging:
      driver: "fluentd"
      options:
        fluentd-address: {{ elk.serverName  }}:{{ elk.fluentBit.port.map }}
        tag: iot.clickhouse
{% endif %}
{% endif %}

# ----------------------------------------------------- Captcha -----------------------------------------------------
{% if iot.captcha.enable %}
  captcha:
    image: "{{ docker_services_map.captcha.image }}"
    deploy:
      replicas: 1
      placement:
        constraints:
          - node.labels.{{ iot.captcha.replication.label }} == yes
    environment:
      - TZ={{ timezone.stdout }}
    volumes:
      - "{{ install_dir }}/captcha/data:/lc-core/data"
{% if iot.captcha.port.export %}
    ports:
      - {{ iot.captcha.port.map }}:8088
{% endif %}
{% if elk.enable %}
    logging:
      driver: "fluentd"
      options:
        fluentd-address: {{ elk.serverName  }}:{{ elk.fluentBit.port.map }}
        tag: iot.captcha
{% endif %}
{% endif %}


# ----------------------------------------------------- ZS-Captcha -----------------------------------------------------
{% if iot.zscaptcha.enable %}
  zs-captcha:
    image: "{{ docker_services_map.zs-captcha.image }}"
    deploy:
      replicas: 1
      placement:
        constraints:
          - node.labels.{{ iot.zscaptcha.replication.label }} == yes
    environment:
      - TZ={{ timezone.stdout }}
      - CAPTCHA_CASE_SENSITIVE={{ 'true' if iot.zscaptcha.caseSensitive else 'false' }}
    volumes:
      - "{{ install_dir }}/captcha/data:/data"
{% if iot.zscaptcha.port.export %}
    ports:
      - {{ iot.zscaptcha.port.map }}:8089
{% endif %}
{% if elk.enable %}
    logging:
      driver: "fluentd"
      options:
        fluentd-address: {{ elk.serverName  }}:{{ elk.fluentBit.port.map }}
        tag: iot.zscaptcha
{% endif %}
{% endif %}


# ------------------------------------------------------ Broker ------------------------------------------------------
{% if not iot.broker.external.enable %}
  broker:
    image: "{{ docker_services_map.broker.image }}"
    labels:
      ru.eltex-co.image.title: iot-mqtt-broker
      ru.eltex-co.image.vendor: ELTEX
      ru.eltex-co.metrics.job: mqtt-broker
      ru.eltex-co.metrics.path: /actuator/prometheus
      ru.eltex-co.metrics.port: {{ iot.broker.internal.port.map }}
    deploy:
      replicas: {{ groups['mqtt_broker'] | length }}
      placement:
        constraints:
          - node.labels.{{ iot.broker.replication.label }} == yes
        max_replicas_per_node: 1
    entrypoint:
      - /extras/app-starter.sh
{% if not iot.mongodb.external.enable %}
      - mongodb:27017:60
{% endif %}
      - rabbitmq:5672:60
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:8083/common/ping"]
      interval: 30s
      timeout: 10s
      retries: 5
      start_period: 3m
    environment:
      - JAVA_TOOL_OPTIONS=-Xms256m -Xmx{{ iot.broker.limits.heap }} {{ "" if not iot.broker.jconsole.enable else "-Dcom.sun.management.jmxremote=true -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.local.only=false -Dcom.sun.management.jmxremote.port=" ~ iot.broker.jconsole.port ~ " -Dcom.sun.management.jmxremote.rmi.port=" ~ iot.broker.jconsole.port ~ " -Djava.rmi.server.hostname=" ~ iot.broker.jconsole.host }}
      - TZ={{ timezone.stdout }}
      - IOT_MQTTBROKER_API_PORT=8083
      - IOT_MQTTBROKER_DISK_USAGE_THRESHOLD_WARN={{ iot.diskUsage.warnThreshold }}
      - IOT_MQTTBROKER_DISK_USAGE_THRESHOLD_CRITICAL={{ iot.diskUsage.criticalThreshold }}
      - IOT_MQTTBROKER_METRICS_TOPIC_COUNTER_ENABLED={{ iot.broker.metrics.topicCounterEnabled }}
      - IOT_MQTT_BROKER_USE_RABBIT_MQ=false
      - IOT_MQTT_BROKER_USE_QUORUM_QUEUES=true
      - IOT_MQTT_BROKER_REPLICA_NAME={{ '{{' }}.Task.Slot{{ '}}' }}
      - IOT_MQTT_BROKER_QUEUE_NAME=mqtt-broker-queue-{{ '{{' }}.Task.Slot{{ '}}' }}
      - HIVEMQ_ROOT_FOLDER={{ iot.broker.hivemq.rootFolder }}
      - SPRING_RABBITMQ_HOST=rabbitmq
      - SPRING_DATA_MONGODB_URI={{ mongodb_uri }}
      - SPRING_DATA_MONGODB_DATABASE={{ iot.broker.db.name }}
      - HAZELCAST_INSTANCE_NAME={{ iot.hazelcast.instanceName }}
      - HAZELCAST_CLUSTER_NAME={{ iot.hazelcast.clusterName }}
      - HAZELCAST_HOST=hazelcast
      - HAZELCAST_PORT=5701
      - LOGGING_CONFIG={{ iot.logbackConfig }}
      - LOGGING_LOGBACK_DIR=/var/log/broker
      - LOGGING_LEVEL_ROOT={{ iot.broker.logLevel }}
      - LOGGING_LEVEL_HIVEMQ={{ iot.broker.logLevel }}
    ports:
      - {{ iot.broker.external.port.map }}:8883
{% if iot.broker.internal.port.export %}
      - {{ iot.broker.internal.port.map }}:8083
{% endif %}
{% if iot.broker.jconsole.enable %}
      - "{{ iot.broker.jconsole.port }}:{{ iot.broker.jconsole.port }}"
{% endif %}
    volumes:
      - "{{ broker_install_dir }}/mqtt/hivemq/:/hivemq/"
      - "{{ broker_install_dir }}/mqtt/var/log/broker:/var/log/broker"
{% if elk.enable %}
    logging:
      driver: "fluentd"
      options:
        fluentd-address: {{ elk.serverName  }}:{{ elk.fluentBit.port.map }}
        tag: iot.mqttbroker
{% endif %}
{% endif %}


# --------------------------------------------------- OlapService ---------------------------------------------------
{% if not iot.olapservice.external.enable %}
  olapservice:
    image: "{{ docker_services_map.olapservice.image }}"
    labels:
      ru.eltex-co.image.title: iot-olapservice
      ru.eltex-co.image.vendor: ELTEX
      ru.eltex-co.metrics.job: olapservice
      ru.eltex-co.metrics.path: /actuator/prometheus
      ru.eltex-co.metrics.port: {{ iot.olapservice.port.map }}
    deploy:
      replicas: {{ iot.olapservice.replication.replicaCount }}
      placement:
        constraints:
          - node.labels.{{ iot.olapservice.replication.label }} == yes
    entrypoint:
      - /extras/app-starter.sh
      - clickhouse:8123:60
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:8023/common/ping"]
      interval: 30s
      timeout: 10s
      retries: 5
      start_period: 20s
    environment:
      - TZ={{ timezone.stdout }}
      - SERVER_PORT=8023
      - SERVICES_DISKUSAGE_WARNTHRESHOLD={{ iot.diskUsage.warnThreshold }}
      - SERVICES_DISKUSAGE_CRITICALTHRESHOLD={{ iot.diskUsage.criticalThreshold }}
      - LOGGING_CONFIG={{ iot.logbackConfig }}
      - LOGGING_LOGBACK_DIR=/var/log/olapservice
      - LOGGING_LEVEL_ROOT={{ iot.olapservice.logLevel }}
      - LOGGING_LEVEL_ORG_JOOQ={{ iot.olapservice.logLevel }}
      - CLICKHOUSE_URL=jdbc:clickhouse://clickhouse:8123
      - CLICKHOUSE_DBNAME={{ iot.clickhouse.db.name }}
      - CLICKHOUSE_USERNAME=iot
      - CLICKHOUSE_PASSWORD=0d3c27fc-0e5e-4bd5-ab10-5037631f4c42
      - CLICKHOUSE_SSL=false
      - CLICKHOUSE_COMPRESS=false
      - CLICKHOUSE_CONNECTION_TIMEOUT=5000
      - SPRING_RABBITMQ_HOST=rabbitmq
      - SPRING_RABBITMQ_PORT=5672
      - SPRING_RABBITMQ_USEQUORUMQUEUES=true
      - SPRING_RABBITMQ_EXCHANGE={{ iot.olapservice.rabbit.exchange.events }}
      - SPRING_RABBITMQ_ENVELOPEQUEUE={{ iot.olapservice.rabbit.queue.save }}
      - SPRING_RABBITMQ_ROUTINGKEY={{ iot.olapservice.rabbit.routingKey.save }}
      - SPRING_RABBITMQ_CONSUMERS_PREFETCHCOUNT={{ iot.olapservice.rabbit.olapservice.prefetchCount }}
      - SPRING_RABBITMQ_CONSUMERS_BATCHSIZE={{ iot.olapservice.rabbit.olapservice.batchSize }}
      - SPRING_RABBITMQ_CONSUMERS_BATCHRECEIVETIMEOUT={{ iot.olapservice.rabbit.olapservice.batchReceiveTimeout }}
      - SPRING_RABBITMQ_CONSUMERS_COUNT={{ iot.olapservice.rabbit.olapservice.consumersCount }}
      - SPRING_RABBITMQ_CONSUMERS_MAXCOUNT={{ iot.olapservice.rabbit.olapservice.consumersMaxCount }}
      - JAVA_TOOL_OPTIONS=-Xms512m -Xmx{{ iot.olapservice.limits.heap }}
{% if iot.olapservice.port.export %}
    ports:
      - {{ iot.olapservice.port.map }}:8023
{% endif %}
    volumes:
      - "{{ olapservice_install_dir }}/olapservice/var/log/olapservice:/var/log/olapservice"
{% if elk.enable %}
    logging:
      driver: "fluentd"
      options:
        fluentd-address: {{ elk.serverName  }}:{{ elk.fluentBit.port.map }}
        tag: iot.olapservice
{% endif %}
{% endif %}

# ---------------------------------------------------- ZwayProxy ----------------------------------------------------
{% if not iot.zwayproxy.external.enable %}
  zwayproxy:
    image: "{{ docker_services_map.zwayproxy.image }}"
    labels:
      ru.eltex-co.image.title: iot-zwayproxy
      ru.eltex-co.image.vendor: ELTEX
      ru.eltex-co.metrics.job: zwayproxy
      ru.eltex-co.metrics.path: /actuator/prometheus
      ru.eltex-co.metrics.port: {{ iot.zwayproxy.port.map }}
    deploy:
      replicas: {{ iot.zwayproxy.replication.replicaCount }}
      placement:
        constraints:
          - node.labels.{{ iot.zwayproxy.replication.label }} == yes
    entrypoint:
      - /extras/app-starter.sh
      - rabbitmq:5672:60
    environment:
      - spring.rabbitmq.host=rabbitmq
      - zwayproxy.rabbit.useQuorumQueues=true
      - zwayproxy.rabbit.queue.platform={{ iot.zwayproxy.rabbit.queue.platform }}
      - zwayproxy.rabbit.queue.proxy=zway-proxy-{{ '{{' }}.Task.Slot{{ '}}' }}
      - zwayproxy.rabbit.exchange.proxy={{ iot.zwayproxy.rabbit.exchange.proxy }}
      - zwayproxy.rabbit.consumers.count={{ iot.zwayproxy.rabbit.proxyConsumers.count }}
      - zwayproxy.rabbit.consumers.maxCount={{ iot.zwayproxy.rabbit.proxyConsumers.maxCount }}
      - logging.level.root={{ iot.zwayproxy.logLevel }}
      - logging.config={{ iot.logbackConfig }}
      - logging.logback.dir=/var/log/elis/{{ '{{' }}.Task.Slot{{ '}}' }}
      - JAVA_TOOL_OPTIONS=-Xms512m -Xmx{{ iot.zwayproxy.limits.heap }}
    volumes:
      - "{{ zwayproxy_install_dir }}/zwayproxy/var/log/elis:/var/log/elis"
{% if iot.zwayproxy.port.export or iot.zwayproxy.sslPort.export %}
    ports:
{% if iot.zwayproxy.port.export %}
      - {{ iot.zwayproxy.port.map }}:8070
{% endif %}
{% if iot.zwayproxy.sslPort.export %}
      - {{ iot.zwayproxy.sslPort.map }}:8072
{% endif %}
{% endif %}
{% if elk.enable %}
    logging:
      driver: "fluentd"
      options:
        fluentd-address: {{ elk.serverName  }}:{{ elk.fluentBit.port.map }}
        tag: iot.zwayproxy
{% endif %}
{% endif %}


# ------------------------------------------------------ WSProxy ------------------------------------------------------
{% if not iot.wsproxy.external.enable %}
  wsproxy:
    image: "{{ docker_services_map.wsproxy.image }}"
    labels:
      ru.eltex-co.image.title: iot-wsproxy
      ru.eltex-co.image.vendor: ELTEX
      ru.eltex-co.metrics.job: wsproxy
      ru.eltex-co.metrics.path: /api/v1/actuator/prometheus
      ru.eltex-co.metrics.port: {{ iot.wsproxy.port.map }}
    deploy:
      replicas: {{ iot.wsproxy.replication.replicaCount }}
      placement:
        constraints:
          - node.labels.{{ iot.wsproxy.replication.label }} == yes
    entrypoint:
      - /extras/app-starter.sh
      - rabbitmq:5672:60
    environment:
      - spring.rabbitmq.host=rabbitmq
      - wsproxy.rabbit.useQuorumQueues=true
      - wsproxy.rabbit.queue.platform={{ iot.wsproxy.rabbit.queue.platform }}
      - wsproxy.rabbit.queue.proxy=ws-proxy-{{ '{{' }}.Task.Slot{{ '}}' }}
      - wsproxy.rabbit.exchange.proxy={{ iot.wsproxy.rabbit.exchange.proxy }}
      - wsproxy.rabbit.consumers.count={{ iot.wsproxy.rabbit.proxyConsumers.count }}
      - wsproxy.rabbit.consumers.maxCount={{ iot.wsproxy.rabbit.proxyConsumers.maxCount }}
      - logging.level.root={{ iot.wsproxy.logLevel }}
      - logging.config={{ iot.logbackConfig }}
      - logging.logback.dir=/var/log/elis/{{ '{{' }}.Task.Slot{{ '}}' }}
      - JAVA_TOOL_OPTIONS=-Xms512m -Xmx{{ iot.wsproxy.limits.heap }}
    volumes:
      - "{{ wsproxy_install_dir }}/wsproxy/var/log/elis:/var/log/elis"
{% if iot.wsproxy.port.export %}
    ports:
      - {{ iot.wsproxy.port.map }}:8075
{% endif %}
{% if elk.enable %}
    logging:
      driver: "fluentd"
      options:
        fluentd-address: {{ elk.serverName  }}:{{ elk.fluentBit.port.map }}
        tag: iot.wsproxy
{% endif %}
{% endif %}

# ------------------------------------------------ Authorization Server ----------------------------------------------
{% if iot.authorization.enable %}
  authorization:
    image: "{{ docker_services_map.authorization.image }}"
    labels:
      ru.eltex-co.image.title: iot-authorization-server
      ru.eltex-co.image.vendor: ELTEX
      ru.eltex-co.metrics.job: authorization-server
      ru.eltex-co.metrics.path: /api/v1/actuator/prometheus
      ru.eltex-co.metrics.port: {{ iot.authorization.port.map }}
    deploy:
      replicas: 1
      placement:
        constraints:
          - node.labels.{{ iot.authorization.replication.label }} == yes
    entrypoint:
      - /extras/app-starter.sh
{% if not iot.mongodb.external.enable %}
      - mongodb:27017:60
{% endif %}
      - rabbitmq:5672:60
{% if iot.captcha.enable %}
      - captcha:8088:60
{% endif %}
{% if iot.zscaptcha.enable %}
      - zs-captcha:8089:60
{% endif %}
      - hazelcast:5701:60
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:{{ iot.authorization.port.map }}/api/v1/common/ping"]
      interval: 30s
      timeout: 10s
      retries: 5
      start_period: 3m
    environment:
      - TZ={{ timezone.stdout }}
      - JAVA_TOOL_OPTIONS=-Xms512m -Xmx{{ iot.authorization.limits.heap }} {{ "" if not iot.authorization.jconsole.enable else "-Dcom.sun.management.jmxremote=true -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.local.only=false -Dcom.sun.management.jmxremote.port=" ~ iot.authorization.jconsole.port ~ " -Dcom.sun.management.jmxremote.rmi.port=" ~ iot.authorization.jconsole.port ~ " -Djava.rmi.server.hostname=" ~ iot.authorization.jconsole.host }}
    volumes:
      - "{{ install_dir }}/authorization/var/log/elis:/var/log/elis"
      - "{{ install_dir }}/authorization/etc/elis:/etc/elis"
      - "{{ install_dir }}/authorization/ssl/certs/authorization-server.crt:/etc/ssl/certs/authorization-server.crt"
      - "{{ install_dir }}/authorization/ssl/private/authorization-server.key:/etc/ssl/private/authorization-server.key"
{% if iot.authorization.port.export or iot.authorization.port.ssl.export or iot.authorization.jconsole.enable %}
    ports:
{% if iot.authorization.port.export %}
      - {{ iot.authorization.port.map }}:{{ iot.authorization.port.map }}
{% endif %}
{% if iot.authorization.port.ssl.export %}
      - {{ iot.authorization.port.ssl.map }}:{{ iot.authorization.port.ssl.map }}
{% endif %}
{% if iot.authorization.jconsole.enable %}
      - {{ iot.authorization.jconsole.port }}:{{ iot.authorization.jconsole.port }}
{% endif %}
{% endif %}
{% if elk.enable %}
    logging:
      driver: "fluentd"
      options:
        fluentd-address: {{ elk.serverName  }}:{{ elk.fluentBit.port.map }}
        tag: iot.authorization
{% endif %}
{% endif %}

# ------------------------------------------------------- Guard ------------------------------------------------------
{% if not iot.guard.external.enable %}
  guard:
    image: "{{ docker_services_map.guard.image }}"
    labels:
      ru.eltex-co.image.title: iot-guard
      ru.eltex-co.image.vendor: ELTEX
      ru.eltex-co.metrics.job: guard
      ru.eltex-co.metrics.path: /api/v1/actuator/prometheus
      ru.eltex-co.metrics.port: {{ iot.guard.port.map }}
    deploy:
      replicas: 1
      placement:
        constraints:
          - node.labels.{{ iot.guard.replication.label }} == yes
    entrypoint:
      - /extras/app-starter.sh
{% if not iot.mongodb.external.enable %}
      - mongodb:27017:60
{% endif %}
      - rabbitmq:5672:60
      - hazelcast:5701:60
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:{{ iot.guard.port.map }}/api/v1/common/ping"]
      interval: 30s
      timeout: 10s
      retries: 5
      start_period: 3m
    environment:
      - TZ={{ timezone.stdout }}
      - JAVA_TOOL_OPTIONS=-Xms512m -Xmx{{ iot.guard.limits.heap }} {{ "" if not iot.guard.jconsole.enable else "-Dcom.sun.management.jmxremote=true -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.local.only=false -Dcom.sun.management.jmxremote.port=" ~ iot.guard.jconsole.port ~ " -Dcom.sun.management.jmxremote.rmi.port=" ~ iot.guard.jconsole.port ~ " -Djava.rmi.server.hostname=" ~ iot.guard.jconsole.host }}
    volumes:
      - "{{ install_dir }}/guard/var/log/elis:/var/log/elis"
      - "{{ install_dir }}/guard/etc/elis:/etc/elis"
      - "{{ install_dir }}/guard/ssl/certs/guard.crt:/etc/ssl/certs/guard.crt"
      - "{{ install_dir }}/guard/ssl/private/guard.key:/etc/ssl/private/guard.key"
{% if iot.guard.port.export or iot.guard.port.ssl.export or iot.guard.jconsole.enable %}
    ports:
{% if iot.guard.port.export %}
      - {{ iot.guard.port.map }}:{{ iot.guard.port.map }}
{% endif %}
{% if iot.guard.port.ssl.export %}
      - {{ iot.guard.port.ssl.map }}:{{ iot.guard.port.ssl.map }}
{% endif %}
{% if iot.guard.jconsole.enable %}
      - {{ iot.guard.jconsole.port }}:{{ iot.guard.jconsole.port }}
{% endif %}
{% endif %}
{% if elk.enable %}
    logging:
      driver: "fluentd"
      options:
        fluentd-address: {{ elk.serverName  }}:{{ elk.fluentBit.port.map }}
        tag: iot.guard
{% endif %}
{% endif %}

{% if iot.payment.enable %}
# ------------------------------------------------------- Payment ------------------------------------------------------
  payment:
    image: "{{ docker_services_map.payment.image }}"
    deploy:
      replicas: 1
      placement:
        constraints:
          - node.labels.{{ iot.payment.replication.label }} == yes
    entrypoint:
      - /extras/app-starter.sh
{% if not iot.mongodb.external.enable %}
      - mongodb:27017:60
{% endif %}
      - rabbitmq:5672:60
      - hazelcast:5701:60
    healthcheck:
      test: [ "CMD", "curl", "-f", "http://localhost:{{ iot.payment.port.map }}/api/v1/common/ping" ]
      interval: 30s
      timeout: 10s
      retries: 5
      start_period: 3m
    environment:
      - TZ={{ timezone.stdout }}
      - JAVA_TOOL_OPTIONS=-Xms512m -Xmx{{ iot.payment.limits.heap }} {{ "" if not iot.payment.jconsole.enable else "-Dcom.sun.management.jmxremote=true -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.local.only=false -Dcom.sun.management.jmxremote.port=" ~ iot.payment.jconsole.port ~ " -Dcom.sun.management.jmxremote.rmi.port=" ~ iot.payment.jconsole.port ~ " -Djava.rmi.server.hostname=" ~ iot.payment.jconsole.host }}
    volumes:
      - "{{ install_dir }}/payment/etc/elis:/etc/elis"
      - "{{ install_dir }}/payment/var/log/elis:/var/log/elis"
      - "{{ install_dir }}/payment/ssl/certs/payment-server.crt:/etc/ssl/certs/payment-server.crt"
      - "{{ install_dir }}/payment/ssl/private/payment-server.key:/etc/ssl/private/payment-server.key"
{% if iot.payment.port.export or iot.payment.port.ssl.export %}
    ports:
{% if iot.payment.port.export %}
      - {{ iot.payment.port.map }}:{{ iot.payment.port.map }}
{% endif %}
{% if iot.payment.port.ssl.export %}
      - {{ iot.payment.port.ssl.map }}:{{ iot.payment.port.ssl.map }}
{% endif %}
{% endif %}
{% if elk.enable %}
    logging:
      driver: "fluentd"
      options:
        fluentd-address: {{ elk.serverName  }}:{{ elk.fluentBit.port.map }}
        tag: iot.payment
{% endif %}
{% endif %}

{% if iot.notification.enable %}
# -------------------------------------------------- Notification ------------------------------------------------------
  notification:
    image: "{{ docker_services_map.notification.image }}"
    labels:
      ru.eltex-co.image.title: iot-notification
      ru.eltex-co.image.vendor: ELTEX
      ru.eltex-co.metrics.job: notification
      ru.eltex-co.metrics.path: /actuator/prometheus
      ru.eltex-co.metrics.port: {{ iot.notification.port.map }}
    deploy:
      replicas: 1
      placement:
        constraints:
          - node.labels.{{ iot.notification.replication.label }} == yes
    entrypoint:
      - /extras/app-starter.sh
{% if not iot.mongodb.external.enable %}
      - mongodb:27017:60
{% endif %}
      - rabbitmq:5672:60
      - hazelcast:5701:60
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:{{ iot.notification.port.map }}/common/ping"]
      interval: 30s
      timeout: 10s
      retries: 5
      start_period: 3m
    environment:
      - TZ={{ timezone.stdout }}
      - JAVA_TOOL_OPTIONS=-Xms512m -Xmx{{ iot.notification.limits.heap }} {{ "" if not iot.notification.jconsole.enable else "-Dcom.sun.management.jmxremote=true -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.local.only=false -Dcom.sun.management.jmxremote.port=" ~ iot.authorization.jconsole.port ~ " -Dcom.sun.management.jmxremote.rmi.port=" ~ iot.notification.jconsole.port ~ " -Djava.rmi.server.hostname=" ~ iot.notification.jconsole.host }}
      - logging.logback.dir=/var/log/elis/{{ '{{' }}.Task.Slot{{ '}}' }}
    volumes:
      - "{{ install_dir }}/notification/var/log/elis:/var/log/elis"
      - "{{ install_dir }}/notification/etc/elis:/etc/elis"
{% if iot.notification.vault.ssl.useTrustStore %}
      - "{{ install_dir }}/notification/ssl/private/vault.jks:/etc/vault.jks"
{% endif %}
{% if iot.notification.port.export or iot.notification.jconsole.enable %}
    ports:
{% if iot.notification.port.export %}
      - {{ iot.notification.port.map }}:{{ iot.notification.port.map }}
{% endif %}
{% if iot.notification.jconsole.enable %}
      - {{ iot.notification.jconsole.port }}:{{ iot.notification.jconsole.port }}
{% endif %}
{% endif %}
{% if elk.enable %}
    logging:
      driver: "fluentd"
      options:
        fluentd-address: {{ elk.serverName  }}:{{ elk.fluentBit.port.map }}
        tag: iot.notification
{% endif %}
{% endif %}

{% if not iot.core.external.enable %}
# --------------------------------------------------------- Core -------------------------------------------------------
  core:
    image: "{{ docker_services_map.core.image }}"
    labels:
      ru.eltex-co.image.title: iot-core
      ru.eltex-co.image.vendor: ELTEX
      ru.eltex-co.metrics.job: core
      ru.eltex-co.metrics.path: /api/v1/actuator/prometheus
      ru.eltex-co.metrics.port: {{ iot.core.port.map }}
    deploy:
      replicas: {{ iot.core.replication.replicaCount }}
      placement:
        constraints:
          - node.labels.{{ iot.core.replication.label }} == yes
    entrypoint:
      - /extras/app-starter.sh
{% if not iot.mongodb.external.enable %}
      - mongodb:27017:60
{% endif %}
      - rabbitmq:5672:60
{% if iot.authorization.enable %}
      - authorization:{{ iot.authorization.port.ssl.map }}:60
{% endif %}
{% if not iot.broker.external.enable %}
      - broker:8883:60
{% endif %}
{% if not iot.olapservice.external.enable %}
      - olapservice:8023:60
{% endif %}
      - hazelcast:5701:60
{% if not iot.minio.external.enable %}
      - minio:9000:60
{% endif %}
{% if not iot.guard.external.enable %}
      - guard:{{ iot.guard.port.map }}:60
{% endif %}
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:{{ iot.core.port.map }}/api/v1/common/ping"]
      interval: 30s
      timeout: 10s
      retries: 5
      start_period: 3m
    environment:
      - TZ={{ timezone.stdout }}
      - JAVA_TOOL_OPTIONS=-Xms512m -Xmx{{ iot.core.limits.heap }} {{ "" if not iot.core.jconsole.enable else "-Dcom.sun.management.jmxremote=true -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.local.only=false -Dcom.sun.management.jmxremote.port=" ~ iot.core.jconsole.port ~ " -Dcom.sun.management.jmxremote.rmi.port=" ~ iot.core.jconsole.port ~ " -Djava.rmi.server.hostname=" ~ iot.core.jconsole.host }}
      - logging.logback.dir=/var/log/eltex-sc/{{ '{{' }}.Task.Slot{{ '}}' }}
    volumes:
      - "{{ core_install_dir }}/core/var/log/eltex-sc:/var/log/eltex-sc"
      - "{{ core_install_dir }}/core/etc/eltex-sc:/etc/eltex-sc"
      - "{{ core_install_dir }}/core/ssl/certs/eltex-sc-api.crt:/etc/ssl/certs/eltex-sc-api.crt"
      - "{{ core_install_dir }}/core/ssl/private/eltex-sc-api.key:/etc/ssl/private/eltex-sc-api.key"
{% if slgate.proxy.useClientCert %}
      - "{{ core_install_dir }}/core/ssl/private/slgate_client.p12:/etc/ssl/private/slgate_client.p12"
{% endif %}
{% if iot.core.voice.clientKeyStoreParams.enable %}
      - "{{ core_install_dir }}/core/ssl/private/asr_client.p12:/etc/ssl/private/asr_client.p12"
{% endif %}
    ports:
      - {{ iot.core.ctlGate.tcpPort }}:{{ iot.core.ctlGate.tcpPort }}
      - {{ iot.core.port.map }}:{{ iot.core.port.map }}
      - {{ iot.core.port.ssl.map }}:{{ iot.core.port.ssl.map }}
{% if iot.core.jconsole.enable %}
      - {{ iot.core.jconsole.port }}:{{ iot.core.jconsole.port }}
{% endif %}
{% if elk.enable %}
    logging:
      driver: "fluentd"
      options:
        fluentd-address: {{ elk.serverName  }}:{{ elk.fluentBit.port.map }}
        tag: iot.core
{% endif %}
{% endif %}

{% if iot.web.enable %}
# ---------------------------------------------------------- Web -------------------------------------------------------
  web:
    image: "{{ docker_services_map.web.image }}"
    cap_add:
          - NET_ADMIN
    deploy:
      replicas: 1
      placement:
        constraints:
          - node.labels.{{ iot.web.replication.label }} == yes
    environment:
      - ENABLE_CERTBOT={{ '1' if iot.web.certbot.enable else '0' }}
      - ENABLE_FAIL2BAN={{ '1' if iot.web.fail2ban.enable else '0' }}
      - SERVER_NAME={{ iot.serverName }}
      - CERTBOT_EMAIL={{ iot.web.certbot.email }}
      - HTTPS_PORT={{ iot.web.httpsPort }}
      - TZ={{ timezone.stdout }}
    volumes:
      - "{{ install_dir }}/web/etc/nginx/nginx.conf:/etc/nginx/nginx.conf"
      - "{{ install_dir }}/web/etc/nginx/conf.d/default.conf:/etc/nginx/conf.d/default.conf"
      - "{{ install_dir }}/web/well-known:/usr/share/eltex-sc-web/www/.well-known"
{% if iot.web.certbot.enable %}
      - "{{ install_dir }}/web/etc/letsencrypt:/etc/letsencrypt"
      - "{{ install_dir }}/web/var/log/letsencrypt:/var/log/letsencrypt"
{% endif %}
      - "{{ install_dir }}/web/ssl/certs/eltex-sc-web.crt:/etc/ssl/certs/eltex-sc-web.crt"
      - "{{ install_dir }}/web/ssl/private/eltex-sc-web.key:/etc/ssl/private/eltex-sc-web.key"
{% include docker_compose_web_additional_volumes ignore missing %}

{% if iot.core.external.enable or not iot.authorization.enable or iot.guard.external.enable %}
    extra_hosts:
{% if iot.core.external.enable %}
      - core:host-gateway
{% endif %}
{% if not iot.authorization.enable %}
      - authorization:host-gateway
{% endif %}
{% if iot.guard.external.enable %}
      - guard:host-gateway
{% endif %}
{% endif %}
    ports:
      - {{ iot.web.httpPort }}:{{ iot.web.httpPort }}
      - {{ iot.web.httpsPort }}:{{ iot.web.httpsPort }}
{% include docker_compose_web_additional_ports ignore missing %}

{% if elk.enable %}
    logging:
      driver: "fluentd"
      options:
        fluentd-address: {{ elk.serverName  }}:{{ elk.fluentBit.port.map }}
        tag: iot.web
{% endif %}
{% endif %}

{% if iot.monitoring.mongodbExporter.enable %}
#-------------------------------------------------- Mongodb exporter ---------------------------------------------------
  mongodbExporter:
    image: "{{ docker_services_map.mongodbExporter.image }}"
    labels:
      ru.eltex-co.image.title: iot-mongodb-exporter
      ru.eltex-co.image.vendor: ELTEX
      ru.eltex-co.metrics.job: mongodb-exporter
      ru.eltex-co.metrics.path: /metrics
      ru.eltex-co.metrics.port: {{ iot.monitoring.mongodbExporter.port.map }}
    deploy:
      replicas: 1
      placement:
        constraints:
          - node.labels.{{ iot.monitoring.mongodbExporter.replication.label }} == yes
    command:
      - --no-mongodb.direct-connect
      - --collect-all
      - --discovering-mode
    environment:
      - MONGODB_URI={{ mongodb_uri }}
{% if iot.monitoring.mongodbExporter.port.export %}
    ports:
      - {{ iot.monitoring.mongodbExporter.port.map }}:9216
{% endif %}
{% if elk.enable %}
    logging:
      driver: "fluentd"
      options:
        fluentd-address: {{ elk.serverName  }}:{{ elk.fluentBit.port.map }}
        tag: iot.mongodbExporter
{% endif %}
{% endif %}

{% if iot.monitoring.nginxExporter.enable %}
#-------------------------------------------------- Nginx exporter -----------------------------------------------------
  nginxExporter:
    image: "{{ docker_services_map.nginxExporter.image }}"
    labels:
      ru.eltex-co.image.title: iot-nginx-exporter
      ru.eltex-co.image.vendor: ELTEX
      ru.eltex-co.metrics.job: nginx-exporter
      ru.eltex-co.metrics.path: /metrics
      ru.eltex-co.metrics.port: {{ iot.monitoring.nginxExporter.port.map }}
    deploy:
      replicas: 1
      placement:
        constraints:
          - node.labels.{{ iot.monitoring.nginxExporter.replication.label }} == yes
    environment:
      - SCRAPE_URI=http://web:{{ iot.web.httpPort }}/nginx_status
      - TELEMETRY_PATH=/metrics
      - NGINX_RETRIES=10
{% if iot.monitoring.nginxExporter.port.export %}
    ports:
      - {{ iot.monitoring.nginxExporter.port.map }}:9113
{% endif %}
{% endif %}

Описание основных параметров платформы умного дома в файле swarm_config.yml.j2:

Жирным шрифтом выделены параметры, для которых необходимо выполнить действие из столбца "Требуемое значение".

ПараметрЗначение по умолчаниюТребуемое значениеОписание
services.core.environment.JAVA_TOOL_OPTIONS-Xms512m -Xmx4g {{ "" if not iot.core.jconsole.enable else "-Dcom.sun.management.jmxremote=true -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.local.only=false -Dcom.sun.management.jmxremote.port=" ~ iot.core.jconsole.port ~ " -Dcom.sun.management.jmxremote.rmi.port=" ~ iot.core.jconsole.port ~ " -Djava.rmi.server.hostname=" ~ iot.core.jconsole.host }}-Xms1024m -Xmx8g {{ "" if not iot.core.jconsole.enable else "-Dcom.sun.management.jmxremote=true -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.local.only=false -Dcom.sun.management.jmxremote.port=" ~ iot.core.jconsole.port ~ " -Dcom.sun.management.jmxremote.rmi.port=" ~ iot.core.jconsole.port ~ " -Djava.rmi.server.hostname=" ~ iot.core.jconsole.host }}

Параметры JVM для запуска ядра платформы умного дома.

Увеличено количество минимальной выделяемой памяти для кучи с 512 МБ до 1024 МБ.

Увеличено количество максимальной выделяемой памяти для кучи с 4 ГБ до 8 ГБ.

services.web.depends_on

    depends_on:
      core:
        condition: service_started

Удалить весь блок services.web.depends_on

Параметры порядка запуска контейнеров при старте платформы умного дома.

Удаление блока services.web.depends_on отключает ожидание старта ядра платформы перед запуском веб-сервера, что позволяет начать принимать HTTP-запросы и перенаправлять пользователей на страницу ожидания подключения к платформе.




6. Сконфигурируйте параметры для работы контейнера MQTT-брокера в файле /etc/ansible-iot/latest/templates/iot/docker-swarm/swarm_config.yml.j2.

sudo nano /etc/ansible-iot/latest/templates/iot/docker-swarm/swarm_config.yml.j2

Структура файла /etc/ansible-iot/latest/templates/iot/docker-swarm/swarm_config.yml.j2:

swarm_config.yml.j2
   # ------------------------------------------------------ Broker ------------------------------------------------------
{% if not iot.broker.external.enable %}
  broker:
    image: "{{ docker_services_map.broker.image }}"
    labels:
      ru.eltex-co.image.title: iot-mqtt-broker
      ru.eltex-co.image.vendor: ELTEX
      ru.eltex-co.metrics.job: mqtt-broker
      ru.eltex-co.metrics.path: /actuator/prometheus
      ru.eltex-co.metrics.port: {{ iot.broker.internal.port.map }}
    deploy:
      replicas: {{ groups['mqtt_broker'] | length }}
      placement:
        constraints:
          - node.labels.{{ iot.broker.replication.label }} == yes
        max_replicas_per_node: 1
    entrypoint:
      - /extras/app-starter.sh
{% if not iot.mongodb.external.enable %}
      - mongodb:27017:60
{% endif %}
      - rabbitmq:5672:60
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:8083/common/ping"]
      interval: 30s
      timeout: 10s
      retries: 5
      start_period: 3m
    environment:
      - JAVA_TOOL_OPTIONS=-Xms256m -Xmx{{ iot.broker.limits.heap }} {{ "" if not iot.broker.jconsole.enable else "-Dcom.sun.management.jmxremote=true -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.local.only=false -Dcom.sun.management.jmxremote.port=" ~ iot.broker.jconsole.port ~ " -Dcom.sun.management.jmxremote.rmi.port=" ~ iot.broker.jconsole.port ~ " -Djava.rmi.server.hostname=" ~ iot.broker.jconsole.host }}
      - TZ={{ timezone.stdout }}
      - IOT_MQTTBROKER_API_PORT=8083
      - IOT_MQTTBROKER_DISK_USAGE_THRESHOLD_WARN={{ iot.diskUsage.warnThreshold }}
      - IOT_MQTTBROKER_DISK_USAGE_THRESHOLD_CRITICAL={{ iot.diskUsage.criticalThreshold }}
      - IOT_MQTTBROKER_METRICS_TOPIC_COUNTER_ENABLED={{ iot.broker.metrics.topicCounterEnabled }}
      - IOT_MQTT_BROKER_USE_RABBIT_MQ=false
      - IOT_MQTT_BROKER_USE_QUORUM_QUEUES=true
      - IOT_MQTT_BROKER_REPLICA_NAME={{ '{{' }}.Task.Slot{{ '}}' }}
      - IOT_MQTT_BROKER_QUEUE_NAME=mqtt-broker-queue-{{ '{{' }}.Task.Slot{{ '}}' }}
      - HIVEMQ_ROOT_FOLDER={{ iot.broker.hivemq.rootFolder }}
      - SPRING_RABBITMQ_HOST=rabbitmq
      - SPRING_DATA_MONGODB_URI={{ mongodb_uri }}
      - SPRING_DATA_MONGODB_DATABASE={{ iot.broker.db.name }}
      - HAZELCAST_INSTANCE_NAME={{ iot.hazelcast.instanceName }}
      - HAZELCAST_CLUSTER_NAME={{ iot.hazelcast.clusterName }}
      - HAZELCAST_HOST=hazelcast
      - HAZELCAST_PORT=5701
      - LOGGING_CONFIG={{ iot.logbackConfig }}
      - LOGGING_LOGBACK_DIR=/var/log/broker
      - LOGGING_LEVEL_ROOT={{ iot.broker.logLevel }}
      - LOGGING_LEVEL_HIVEMQ={{ iot.broker.logLevel }}
    ports:
      - {{ iot.broker.external.port.map }}:8883
{% if iot.broker.internal.port.export %}
      - {{ iot.broker.internal.port.map }}:8083
{% endif %}
{% if iot.broker.jconsole.enable %}
      - "{{ iot.broker.jconsole.port }}:{{ iot.broker.jconsole.port }}"
{% endif %}
    volumes:
      - "{{ broker_install_dir }}/mqtt/hivemq/:/hivemq/"
      - "{{ broker_install_dir }}/mqtt/var/log/broker:/var/log/broker"
{% if elk.enable %}
    logging:
      driver: "fluentd"
      options:
        fluentd-address: {{ elk.serverName  }}:{{ elk.fluentBit.port.map }}
        tag: iot.mqttbroker
{% endif %}
{% endif %}


Описание основных параметров платформы умного дома в файле broker/include/docker-compose.yml.j2:

ПараметрЗначение по умолчаниюТребуемое значениеОписание
broker.environment.JAVA_TOOL_OPTIONS-Xms256m -Xmx4g {{ "" if not iot.broker.jconsole.enable else "-Dcom.sun.management.jmxremote=true -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.local.only=false -Dcom.sun.management.jmxremote.port=" ~ iot.broker.jconsole.port ~ " -Dcom.sun.management.jmxremote.rmi.port=" ~ iot.broker.jconsole.port ~ " -Djava.rmi.server.hostname=" ~ iot.broker.jconsole.host }}-Xms512m -Xmx6g {{ "" if not iot.broker.jconsole.enable else "-Dcom.sun.management.jmxremote=true -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.local.only=false -Dcom.sun.management.jmxremote.port=" ~ iot.broker.jconsole.port ~ " -Dcom.sun.management.jmxremote.rmi.port=" ~ iot.broker.jconsole.port ~ " -Djava.rmi.server.hostname=" ~ iot.broker.jconsole.host }}

Параметры JVM для запуска MQTT брокера.

Увеличено количество минимальной выделяемой памяти для кучи с 256 МБ до 512 МБ.

Увеличено количество максимальной выделяемой памяти для кучи с 4 ГБ до 6 ГБ.





  • Нет меток