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

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

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

[iot]
localhost       ansible_connection=local        ansible_sudo_pass=password
[mqtt_broker]
localhost       ansible_connection=local        ansible_sudo_pass=password
[olap_service]
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:

# Параметры установки платформы.
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 должна быть настроена, а параметры подключения нужно указать в 'addr' и 'port'.
      enable: false
      # Адрес внешней MongoDB.
      addr: "external.mongodb.address"
      # Порт внешней MongoDB.
      port: 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

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

    # Уровень сложности captcha: 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

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

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

    push:
      firebase:
        enabled: false
      apns:
        enabled: false

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

    acquiring:
      # Период после завершения действия последней подписки, в течение которого услуга продолжает (ограниченно) действовать
      advancePeriod: 3d
      paykeeper:
        url: "CHANGE_ME"
        secret: "PaykeeperSecretChangeMe"
        user: "PaykeeperUsernameChangeMe"
        password: "PaykeeperPasswordChangeMe"

    # Настройки ИК-пульта.
    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] и [monitoring] должны совпадать.
  serverName: "{{ iot.serverName }}"
  # Директория для установки системы логирования.
  installDir: /storage/elk

Описание основных параметров платформы умного дома в файле 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:

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

swarm:
  enabled: false
  # Имя stack для запуска в docker-swarm.
  stack: swarm_iot

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

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

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

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

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

# Параметры сервисов IoT (для docker-compose), сгруппированные по именам.
# 'enable' — должен ли присутствовать сервис в docker-compose.yml.
# 'port.map' — номер порта сервиса в сети хоста.
# 'port.export' — нужно ли выполнять маппинг порта из контейнера в сеть хоста.
# 'db.name' — имя БД, используемой сервисом (связкой сервисов).
iot:
  # Параметры мониторинга использования дискового пространства. Должны соответствовать требованию:
  # warnThreshold > criticalThreshold > 0, иначе мониторинг дискового пространства будет отключен.
  diskUsage:
    # Порог дискового пространства (в %), при достижении которого все логгеры микросервисов переводятся в режим WARN
    # (отображаются сообщения с тегами WARN и ERROR). Количество бэкапов баз уменьшается пропорционально приближению к
    # порогу criticalThreshold.
    warnThreshold: 20
    # Порог дискового пространства (в %), при достижении которого все логгеры микросервисов переводятся в режим ERROR
    # (отображаются только сообщения с тегом ERROR). Бэкапы баз не выполняются.
    criticalThreshold: 10
  # Нужно ли установить лимиты на сервисы в docker compose.
  limits:
    enable: false
  replication:
    core:
      enabled: false
      replicaCount: 1
    mqttBroker:
      enabled: false
      replicaCount: 2
    zwayproxy:
      enabled: false
      replicaCount: 1
    wsproxy:
      enabled: false
      replicaCount: 1
  mongodb:
    limits:
      enable: false
      cpus: 1.0
      memory: 4G
    port:
      map: 27017
      export: false
  broker:
    logLevel: INFO
    limits:
      enable: true
      cpus: 1.0
      memory: 4G
    external:
      # Будет ли развернут брокер на стороннем хосте.
      enable: false
      # Нужно ли устанавливать брокер на сторонний хост средствами Ansible.
      install: false
      # Если установка брокера на сторонний хост будет выполняться средствами Ansible, то в какую директорию.
      installDir: /storage/broker
      # Внешний адрес стороннего хоста, по которому к брокеру будут подключаться платформа и устройства.
      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/
  olapservice:
    logLevel: INFO
    limits:
      enable: true
      cpus: 1.0
      memory: 4G
    external:
      # Будет ли развернут olapservice на стороннем хосте.
      enable: false
      # Нужно ли устанавливать olapservice на сторонний хост средствами ansible.
      install: false
      # Если установка olapservice на сторонний хост будет выполняться средствами ansible, то в какую директорию.
      installDir: /storage/olapservice
      # Внешний адрес стороннего хоста, по которому платформа будет подключаться к olapservice'у.
      host: "external.olapservice.address"
    port:
      map: 8023
      export: false
    db:
      name: iotcore
      # Нужно ли устанавливать clickhouse (полезно для разработки olapservice).
      install: true
      limits:
        enable: false
        cpus: 1.0
        memory: 4G
      port:
        map: 8123
        export: false
  captcha:
    enable: true
    limits:
      enable: true
      cpus: 1.0
      memory: 4G
    port:
      map: 8088
      export: false
    caseSensitive: true
    allowedSizes:
      - "312x45"
      - "270x40"
    instance: "captcha:8088"
    proportion: 100
  zscaptcha:
    enable: false
    limits:
      enable: true
      cpus: 1.0
      memory: 4G
    port:
      map: 8089
      export: false
    caseSensitive: true
    instance: "zs-captcha:8089"
    proportion: 0
  authorization:
    # Развертывание окружения без auth server, полезно для разработки auth server.
    enable: true
    # API-ключ для авторизации HTTP-запросов в сервис авторизации от внешних систем, таких как Core.
    # Специальное значение 'autogenerated' подразумевает, что apiKey будет сгенерирован в процессе установки.
    apiKey: "autogenerated"
    limits:
      enable: true
      cpus: 1.0
      memory: 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"
    swagger:
      enable: false
    rabbit:
      eventQueue:
        name: platform-rpc-event-queue
      # Количество консьюмеров на стороне платформы
      platformConsumers:
        # Данный параметр не может быть больше чем maxCount.
        count: 16
        # Максимальное количество одновременных консьюмеров очереди.
        maxCount: 16
  core:
    # Развертывание окружения без платформы, полезно для разработки core.
    enable: true
    limits:
      enable: true
      cpus: 1.0
      memory: 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
      threadPools:
        main:
          size: 16
    olapservice:
      # Нужно ли платформе пытаться подключиться к OlapService.
      enable: true
    mjollnir:
      # URL для Mjollnir.
      url: "http://lab3-test.eltex.loc:8878/api/v1"
    slgate:
      instances:
        - slgate:4443
      ignoreServerCertCheck: false
    video:
      evi:
        ignoreServerCertCheck: false
        checkEventSenderAddress: true
      # Параметры 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
  web:
    # Развертывание окружения без WEB, полезно для разработки web.
    enable: true
    limits:
      enable: true
      cpus: 1.0
      memory: 4G
  hazelcast:
    clusterName: iot-core
    instanceName: iot-core-hazelcast-instance
    limits:
      enable: true
      cpus: 1.0
      memory: 4G
    external:
      port:
        map: 5701
        export: false
  rabbitmq:
    limits:
      enable: true
      cpus: 1.0
      memory: 4G
    admin:
      user: guest
      password: guest
      port:
        map: 15671
        export: true
      sslPort:
        map: 15672
        export: true
    port:
      map: 5672
      export: false
  zwayproxy:
    enable: true
    logLevel: INFO
    external:
      enable: false
    limits:
      enable: true
      cpus: 1.0
      memory: 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
      # Адрес хоста, куда nginx будет проксировать запросы.
      host: "1.2.3.4"
      port: 8075
    limits:
      enable: true
      cpus: 1.0
      memory: 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

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

# Параметры сервисов мониторинга (для docker-compose), сгруппированные по именам.
# 'port.map' — номер порта сервиса в сети хоста.
# 'port.export' — нужно ли выполнять маппинг порта из контейнера в сеть хоста.
monitoring:
  prometheus:
    port:
      map: 9090
    # Период опроса сервисов со стороны Prometheus в секундах. Небольшие значения (менее десятков секунд) значительно
    # увеличат нагрузку на сеть.
    # При изменении параметра рекомендуется поменять переменную grafana.scrapeInterval на значение не ниже указанного
    # для Prometheus, чтобы не терять метрики.
    scrapeInterval: 60
  grafana:
    port:
      map: 3000
    # Период опроса Prometheus со стороны Grafana в секундах.
    scrapeInterval: 60
  nginxExporter:
    enable: false
    port:
      map: 9113

Описание основных параметров платформы умного дома в файле 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:

server:
  # Доменное имя сервера, на котором развернута платформа
  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:
      guardUserPassword: "42211224"
      # Максимально допустимое время отсутствия активности со стороны пользователя
      # перед его деактивацией
      allowedInactivePeriod: 180d
      selfRegistration:
        allow: {{ 'true' if iot.authorization.selfRegistration.allow else 'false' }}
        allowDemo: {{ 'true' if iot.authorization.selfRegistration.allowDemo else 'false' }}

  # Параметры для подключения к внешним сервисам, а также параметры внутренних сервисов (компонентов) платформы,
  # обеспечивающих работу с внешними сервисами.
  external:
    captcha:
      # Список инстансов 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:
        eventQueue:
          name: {{ iot.authorization.rabbit.eventQueue.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 }}

db:
  host: "{{ mongodb_addr }}"
  port: {{ mongodb_port }}
  user: ""
  password: ""
  database: "{{ iot.authorization.db.name }}"
  # Используется для миграции, переносящей авторизационные сущности из БД core в БД authorization server
  coreDatabase: "{{ iot.core.db.name }}"

spring:
  security:
    oauth2:
      # API-ключ для авторизации HTTP-запросов в сервис авторизации от внешних систем, таких как Core.
      apiKey: "{{ authorization_server_api_key }}"
      # Время жизни 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.com/authorize"
            token-uri: "https://oauth.vk.com/access_token"
            user-info-uri: "https://api.vk.com/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}/{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}/{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}/{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}/{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}/{action}/oauth2/code/{registrationId}"
            scope:
              - userinfo
{% endif %}
{% endif %}
  mail:
    host: "{{ 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: WARN
    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-compose/base/docker-compose.yml.j2

sudo nano /etc/ansible-iot/latest/templates/iot/docker-compose/base/docker-compose.yml.j2

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

services:

{% if not iot.mongodb.external.enable %}
{% include "templates/iot/docker-compose/db/include/docker-compose.yml.j2" ignore missing %}
{% endif %}


{% if not iot.broker.external.enable %}
{% include "templates/iot/docker-compose/broker/include/docker-compose.yml.j2" ignore missing %}
{% endif %}

  # ----------------------------------------------------- Hazelcast ----------------------------------------------------

  hazelcast:
    image: "{{ registry }}{{ registry_iot_subdir }}/iot-hazelcast:{{ release }}"
    container_name: "iot-hazelcast{{ containerNameSuffix }}"
{% if iot.limits.enable and iot.hazelcast.limits.enable %}
    deploy:
      resources:
        limits:
          cpus: '{{ iot.hazelcast.limits.cpus }}'
          memory: {{ iot.hazelcast.limits.memory }}
{% endif %}
    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 %}
    restart: unless-stopped

  # ----------------------------------------------------- RabbitMQ -----------------------------------------------------

  rabbitmq:
    image: "{{ registry }}{{ registry_iot_subdir }}/iot-rabbitmq:{{ release }}"
    container_name: "iot-rabbitmq{{ containerNameSuffix }}"
{% if iot.limits.enable and iot.rabbitmq.limits.enable %}
    deploy:
      resources:
        limits:
          cpus: '{{ iot.rabbitmq.limits.cpus }}'
          memory: {{ iot.rabbitmq.limits.memory }}
{% endif %}
    environment:
      - RABBITMQ_DEFAULT_USER={{ iot.rabbitmq.admin.user }}
      - RABBITMQ_DEFAULT_PASS={{ iot.rabbitmq.admin.password }}
    healthcheck:
      test: rabbitmq-diagnostics -q ping
      interval: 30s
      timeout: 10s
      retries: 3
{% if iot.rabbitmq.port.export or iot.zwayproxy.external.enable or iot.wsproxy.external.enable or iot.rabbitmq.admin.port.export or iot.rabbitmq.admin.sslPort.export %}
    ports:
{% if iot.rabbitmq.port.export or iot.zwayproxy.external.enable or iot.wsproxy.external.enable %}
      - {{ iot.rabbitmq.port.map }}:5672
{% endif %}
{% if iot.rabbitmq.admin.port.export %}
      - {{ iot.rabbitmq.admin.port.map }}:15671
{% endif %}
{% if iot.rabbitmq.admin.sslPort.export %}
      - {{ iot.rabbitmq.admin.sslPort.map }}:15672
{% endif %}
{% endif %}
    restart: unless-stopped

  # ---------------------------------------------------- ZwayProxy -----------------------------------------------------

{% if iot.zwayproxy.enable and not iot.zwayproxy.external.enable %}
  zwayproxy:
    image: "{{ registry }}{{ registry_iot_subdir }}/iot-zwayproxy:{{ release }}"
    container_name: "iot-zwayproxy{{ containerNameSuffix }}"
{% if iot.limits.enable and iot.zwayproxy.limits.enable %}
    deploy:
      resources:
        limits:
          cpus: '{{ iot.zwayproxy.limits.cpus }}'
          memory: {{ iot.zwayproxy.limits.memory }}
{% endif %}
    depends_on:
      rabbitmq:
        condition: service_healthy
    environment:
      - spring.rabbitmq.host=rabbitmq
      - zwayproxy.rabbit.queue.platform={{ iot.zwayproxy.rabbit.queue.platform }}
      - zwayproxy.rabbit.queue.proxy=zway-proxy-1
      - 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 }}
{% if elk.enable %}
      - logging.logstash.host={{ elk.serverName }}
      - logging.logstash.port={{ elk.logstash.port.map }}
{% endif %}
    volumes:
      - "{{ 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 %}
    restart: unless-stopped
{% endif %}

  # ------------------------------------------------------ WSProxy -----------------------------------------------------

{% if not iot.wsproxy.external.enable %}
  wsproxy:
    image: "{{ registry }}{{ registry_iot_subdir }}/iot-wsproxy:{{ release }}"
    container_name: "iot-wsproxy{{ containerNameSuffix }}"
{% if iot.limits.enable and iot.wsproxy.limits.enable %}
    deploy:
      resources:
        limits:
          cpus: '{{ iot.wsproxy.limits.cpus }}'
          memory: {{ iot.wsproxy.limits.memory }}
{% endif %}
    depends_on:
      rabbitmq:
        condition: service_healthy
    environment:
      - server.tomcat.max-connections={{ iot.wsproxy.maxConnections }}
      - spring.rabbitmq.host=rabbitmq
      - wsproxy.rabbit.queue.platform={{ iot.wsproxy.rabbit.queue.platform }}
      - wsproxy.rabbit.queue.proxy=ws-proxy-1
      - 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 }}
{% if elk.enable %}
      - logging.logstash.host={{ elk.serverName }}
      - logging.logstash.port={{ elk.logstash.port.map }}
{% endif %}
    volumes:
      - "{{ install_dir }}/wsproxy/var/log/elis:/var/log/elis"
{% if iot.wsproxy.port.export %}
    ports:
      - {{ iot.wsproxy.port.map }}:8075
{% endif %}
    restart: unless-stopped
{% endif %}

{% if not iot.olapservice.external.enable or (not iot.olapservice.external.install and iot.olapservice.db.install) %}
{% include "templates/iot/docker-compose/olapservice/include/db/docker-compose.yml.j2" ignore missing %}
{% endif %}


{% if not iot.olapservice.external.enable %}
{% include "templates/iot/docker-compose/olapservice/include/docker-compose.yml.j2" ignore missing %}
{% endif %}

  # ----------------------------------------------------- Captcha ------------------------------------------------------

{% if iot.captcha.enable %}
  captcha:
    image: "{{ registry }}{{ registry_iot_subdir }}/iot-captcha:{{ release }}"
    container_name: "iot-captcha{{ containerNameSuffix }}"
{% if iot.limits.enable and iot.captcha.limits.enable %}
    deploy:
      resources:
        limits:
          cpus: '{{ iot.captcha.limits.cpus }}'
          memory: {{ iot.captcha.limits.memory }}
{% endif %}
    environment:
      - TZ={{ timezone.stdout }}
    volumes:
      - "{{ install_dir }}/captcha/data:/lc-core/data"
{% if iot.captcha.port.export %}
    ports:
      - {{ iot.captcha.port.map }}:8088
{% endif %}
    restart: unless-stopped
{% endif %}

{% if iot.zscaptcha.enable %}
  zs-captcha:
    image: "{{ registry }}{{ registry_iot_subdir }}/iot-zs-captcha:{{ release }}"
    container_name: "iot-zs-captcha{{ containerNameSuffix }}"
{% if iot.limits.enable and iot.zscaptcha.limits.enable %}
    deploy:
      resources:
        limits:
          cpus: '{{ iot.zscaptcha.limits.cpus }}'
          memory: {{ iot.zscaptcha.limits.memory }}
{% endif %}
    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 %}
    restart: unless-stopped
{% endif %}

  # ------------------------------------------------ Authorization Server ----------------------------------------------

{% if iot.authorization.enable %}
  authorization-server:
    image: "{{ registry }}{{ registry_iot_subdir }}/iot-authorization-server:{{ release }}"
    container_name: "iot-authorization-server{{ containerNameSuffix }}"
{% if iot.limits.enable and iot.authorization.limits.enable %}
    deploy:
      resources:
        limits:
          cpus: '{{ iot.authorization.limits.cpus }}'
          memory: {{ iot.authorization.limits.memory }}
{% endif %}
    depends_on:
{% if not iot.mongodb.external.enable %}
      db:
        condition: service_started
{% endif %}
      rabbitmq:
        condition: service_healthy
{% if iot.captcha.enable %}
      captcha:
        condition: service_started
{% endif %}
{% if iot.zscaptcha.enable %}
      zs-captcha:
        condition: service_started
{% endif %}
      hazelcast:
        condition: service_started
    links:
{% if not iot.mongodb.external.enable %}
      - db
{% endif %}
{% if iot.captcha.enable %}
      - captcha
{% endif %}
{% if iot.zscaptcha.enable %}
      - zs-captcha
{% endif %}
{% if not iot.wsproxy.external.enable %}
      - wsproxy
{% endif %}
    entrypoint:
      - /extras/app-starter.sh
    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 -Xmx4g {{ "" 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/lib/elis:/var/lib/elis"
      - "{{ install_dir }}/authorization/var/log/elis:/var/log/elis"
      - "{{ install_dir }}/authorization/etc/elis:/etc/elis"
      - "{{ install_dir }}/ssl/certs/authorization-server.crt:/etc/ssl/certs/authorization-server.crt"
      - "{{ install_dir }}/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 %}
    restart: unless-stopped
{% endif %}

  # ------------------------------------------------------- Core -------------------------------------------------------

{% if iot.core.enable %}
  core:
    image: "{{ registry }}{{ registry_iot_subdir }}/iot-core:{{ release }}"
    container_name: "iot-core{{ containerNameSuffix }}"
{% if iot.limits.enable and iot.core.limits.enable %}
    deploy:
      resources:
        limits:
          cpus: '{{ iot.core.limits.cpus }}'
          memory: {{ iot.core.limits.memory }}
{% endif %}
    depends_on:
{% if not iot.mongodb.external.enable %}
      db:
        condition: service_started
{% endif %}
      rabbitmq:
        condition: service_healthy
{% if iot.authorization.enable %}
      authorization-server:
        condition: service_healthy
{% endif %}
{% if not iot.broker.external.enable %}
      broker:
        condition: service_healthy
{% endif %}
{% if not iot.olapservice.external.enable %}
      olapservice:
        condition: service_healthy
{% endif %}
      hazelcast:
        condition: service_started
    links:
{% if not iot.mongodb.external.enable %}
      - db
{% endif %}
{% if not iot.broker.external.enable %}
      - broker
{% endif %}
{% if not iot.olapservice.external.enable %}
      - olapservice
{% endif %}
{% if iot.zwayproxy.enable and not iot.zwayproxy.external.enable %}
      - zwayproxy
{% endif %}
{% if not iot.wsproxy.external.enable %}
      - wsproxy
{% endif %}
    entrypoint:
      - /extras/app-starter.sh
    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 -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 }}
    volumes:
      - "{{ install_dir }}/core/var/lib/eltex-sc:/var/lib/eltex-sc"
      - "{{ install_dir }}/core/var/log/eltex-sc:/var/log/eltex-sc"
      - "{{ install_dir }}/core/etc/eltex-sc:/etc/eltex-sc"
      - "{{ install_dir }}/ssl/certs/eltex-sc-api.crt:/etc/ssl/certs/eltex-sc-api.crt"
      - "{{ install_dir }}/ssl/certs/eltex-sc-ctl-gate.crt:/etc/ssl/certs/eltex-sc-ctl-gate.crt"
      - "{{ install_dir }}/ssl/private/eltex-sc-api.key:/etc/ssl/private/eltex-sc-api.key"
      - "{{ install_dir }}/ssl/private/eltex-sc-ctl-gate.key:/etc/ssl/private/eltex-sc-ctl-gate.key"
{% if slgate.proxy.useClientCert %}
      - "{{ install_dir }}/ssl/private/slgate_client.p12:/etc/ssl/private/slgate_client.p12"
{% endif %}
    ports:
      - {{ iot.core.ctlGate.tcpPort }}:{{ iot.core.ctlGate.tcpPort }}
{% if not iot.zwayproxy.enable %}
      - {{ iot.core.ctlGate.port }}:{{ iot.core.ctlGate.port }}
      - {{ iot.core.ctlGate.sslPort }}:{{ iot.core.ctlGate.sslPort }}
{% endif %}
{% if iot.core.port.export %}
      - {{ iot.core.port.map }}:{{ iot.core.port.map }}
{% endif %}
{% if iot.core.port.ssl.export %}
      - {{ iot.core.port.ssl.map }}:{{ iot.core.port.ssl.map }}
{% endif %}
{% if iot.core.jconsole.enable %}
      - {{ iot.core.jconsole.port }}:{{ iot.core.jconsole.port }}
{% endif %}
    restart: unless-stopped
{% endif %}

  # ------------------------------------------------------- Web --------------------------------------------------------

{% if iot.web.enable %}
  web:
    image: "{{ registry }}{{ registry_iot_subdir }}/iot-double-web:{{ release }}"
    container_name: "iot-double-web{{ containerNameSuffix }}"
    cap_add:
          - NET_ADMIN
{% if iot.limits.enable and iot.web.limits.enable %}
    deploy:
      resources:
        limits:
          cpus: '{{ iot.web.limits.cpus }}'
          memory: {{ iot.web.limits.memory }}
{% endif %}
{% if iot.core.enable %}
    depends_on:
      core:
        condition: service_started
    links:
      - core
{% endif %}
    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 }}/ssl/certs/eltex-sc-web.crt:/etc/ssl/certs/eltex-sc-web.crt"
      - "{{ install_dir }}/ssl/private/eltex-sc-web.key:/etc/ssl/private/eltex-sc-web.key"
{% include docker_compose_web_additional_volumes ignore missing %}

{% if not iot.core.enable %}
      - "{{ install_dir }}/web/etc/dnsmasq.d/core.conf:/etc/dnsmasq.d/core.conf"
{% endif %}
{% if not iot.authorization.enable %}
      - "{{ install_dir }}/web/etc/dnsmasq.d/authorization-server.conf:/etc/dnsmasq.d/authorization-server.conf"
{% endif %}
{% if not iot.core.enable or not iot.authorization.enable %}
    extra_hosts:
{% if not iot.core.enable %}
      - core:host-gateway
{% endif %}
{% if not iot.authorization.enable %}
      - authorization-server: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 %}

    restart: unless-stopped
{% endif %}

networks:
  default:
    name: "iot{{ networkNameSuffix }}"
    external: true

Описание основных параметров платформы умного дома в файле base/docker-compose.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-compose/broker/include/docker-compose.yml.j2

sudo nano /etc/ansible-iot/latest/templates/iot/docker-compose/broker/include/docker-compose.yml.j2

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

  # ------------------------------------------------------ Broker ------------------------------------------------------

  broker:
    image: "{{ registry }}{{ registry_iot_subdir }}/iot-mqttbroker-mongo:{{ release }}"
    container_name: "iot-mqtt-broker{{ containerNameSuffix }}"
{% if iot.limits.enable and iot.broker.limits.enable %}
    deploy:
      resources:
        limits:
          cpus: '{{ iot.broker.limits.cpus }}'
          memory: {{ iot.broker.limits.memory }}
{% endif %}
{% if not iot.mongodb.external.enable %}
    depends_on:
      - db
    links:
      - db
{% endif %}
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:8083/common/ping"]
      interval: 30s
      timeout: 10s
      retries: 5
      start_period: 3m
    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 }}
      - 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_MQTT_BROKER_USE_RABBIT_MQ={{ iot.replication.mqttBroker.enabled }}
      - HIVEMQ_ROOT_FOLDER={{ iot.broker.hivemq.rootFolder }}
      - SPRING_RABBITMQ_HOST=rabbitmq
      - SPRING_DATA_MONGODB_URI=mongodb://{{ mongodb_addr }}:{{ mongodb_port }}
      - SPRING_DATA_MONGODB_DATABASE={{ iot.broker.db.name }}
      - LOGGING_CONFIG={{ iot.logbackConfig }}
      - LOGGING_LOGBACK_DIR=/var/log/broker
{% if elk.enable %}
      - LOGGING_LOGSTASH_HOST={{ elk.serverName }}
      - LOGGING_LOGSTASH_PORT={{ elk.logstash.port.map }}
{% endif %}
      - 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 or iot.broker.external.enable %}
      - {{ iot.broker.internal.port.map }}:8083
{% endif %}
{% if iot.broker.jconsole.enable %}
      - {{ iot.broker.jconsole.port }}:{{ iot.broker.jconsole.port }}
{% endif %}
    volumes:
      - "{{ install_dir }}/mqtt/hivemq/:/hivemq/"
      - "{{ install_dir }}/mqtt/var/log/broker:/var/log/broker"
    restart: unless-stopped

Описание основных параметров платформы умного дома в файле 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 ГБ.




7. Сконфигурируйте параметры веб-сервера платформы умного дома в файле /etc/ansible-iot/latest/templates/iot/web/base_config.j2

sudo nano /etc/ansible-iot/latest/templates/iot/web/base_config.j2

Структура файла /etc/ansible-iot/latest/templates/iot/web/base_config.j2:

# IoT server configuration
{% if iot.web.nginx.rateLimit.enable %}
limit_req_zone $binary_remote_addr zone=perip:10m rate=30r/m;
limit_req_zone $binary_remote_addr zone=api_perip:10m rate=60r/m;
{% endif %}

proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=STATIC:60m max_size=256m inactive=24h use_temp_path=off;

{% if iot.web.redirectHttpToHttps %}
server {
    listen {{ iot.web.httpPort }};

    server_name {{ iot.serverName }};
  
    # use internal dnsmasq for resolving hostnames from /etc/hosts inside docker container
    resolver 127.0.0.1 valid=10s;

    location ~ ^/api/v1/(?:ctl/.+/zway/backup|files/download/.+) {
        proxy_pass http://core:{{ iot.core.port.map }}$request_uri;
        add_header X-Cache-Status $upstream_cache_status;
        proxy_cache STATIC;
        proxy_cache_key "$request_method$host$request_uri";
        proxy_ignore_headers Expires Cache-Control Set-Cookie Vary;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header Host $http_host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_cache_valid 200 24h;
        client_max_body_size 20M;
    }

    location / {
{% if iot.web.httpsPort != 443 %}
        return 301 https://$host:{{ iot.web.httpsPort }}$request_uri;
{% else %}
        return 301 https://$host$request_uri;
{% endif %}
    }
}
{% endif %}

server {
{% if not iot.web.redirectHttpToHttps %}
    listen {{ iot.web.httpPort }};
{% endif %}
    listen {{ iot.web.httpsPort }} ssl;

{% include web_ssl_parameters %}


    root /usr/share/eltex-sc-web/www/;

    index index.html;

    server_name {{ iot.serverName }};

    # use internal dnsmasq for resolving hostnames from /etc/hosts inside docker container
    resolver 127.0.0.1 valid=10s;

    # use gzip compression
    gzip on;
    gzip_vary on;
    gzip_proxied any;
    gzip_comp_level 6;
    gzip_buffers 16 8k;
    gzip_http_version 1.1;
    gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript font/woff2;

    location =/ {
        rewrite ^(.+)$ /ko permanent;
    }

    location ~* ^/api/v1/files/download/.+ {
        proxy_pass http://core:{{ iot.core.port.map }}$request_uri;
        add_header X-Cache-Status $upstream_cache_status;
        proxy_cache STATIC;
        proxy_cache_key "$request_method$host$request_uri";
        proxy_ignore_headers Expires Cache-Control Set-Cookie Vary;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header Host $http_host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_cache_valid 200 24h;
        client_max_body_size 20M;
    }

    location /ko/ {
        # kill browser cache for all html pages
        add_header Last-Modified $date_gmt;
        add_header Cache-Control 'no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0';
        if_modified_since off;
        expires off;
        etag off;

        try_files $uri $uri/ /ko/index.html;
    }

    location ~* (\.html|js/web-version\.js)$ {
        # kill browser cache for all html pages
        add_header Last-Modified $date_gmt;
        add_header Cache-Control 'no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0';
        if_modified_since off;
        expires off;
        etag off;
        try_files $uri =404;
    }

    location ~ ^/(firebase-messaging-sw|js/firebase-app-compat|js/firebase-messaging-compat|js/ajv.min).js {
        try_files /ko/$uri =404;
    }

    location /ko/js/conf.js {
        set $apiAddress $scheme://$http_host;
        set $apiAddressJs "localStorage.setItem('apiAddress', '$apiAddress/api/v1');";
        set $wsAddressJs "localStorage.setItem('wsAddress', '$apiAddress/api/v1/stomp');";
        default_type application/javascript;
        return 200 "$apiAddressJs\n$wsAddressJs";
    }

    location /ng/assets/config.json {
        set $apiAddress $scheme://$http_host;
        set $api "\"api\": \"$apiAddress/api/v1\"";
        set $ws "\"ws\": \"$apiAddress/api/v1/stomp\"";
        set $apiEvi "\"api_evi\": \"$apiAddress/evi/vsaas/api/v2\"";
        set $stunUrls "\"stunUrls\":[ \"{{ iot.core.video.webrtc.stun.urls | join('\\\", \\\"') }}\" ]";
        default_type application/json;
        return 200 "{ $api, $ws, $apiEvi, $stunUrls }";
    }

    location /ng/ {
        # kill browser cache for all html pages
        add_header Last-Modified $date_gmt;
        add_header Cache-Control 'no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0';
        if_modified_since off;
        expires off;
        etag off;

        try_files $uri /ng/index.html;
    }

    location ~ ^/api/v1/(?:login|images|oauth2|captcha|emailChange|users/logins|user/deleteyourself|profiles|security/roles|password|registration) {
{% if iot.web.nginx.rateLimit.enable %}
        limit_req zone=perip burst=20 nodelay;
{% endif %}
        proxy_buffering off;
        proxy_pass https://authorization-server:{{ iot.authorization.port.ssl.map }}$request_uri;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header Host $http_host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Real-IP $remote_addr;
        client_max_body_size 15M;
    }

    location /api/v1/sber {
        proxy_buffering off;
        proxy_pass https://core:{{ iot.core.port.ssl.map }}$request_uri;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header Host $http_host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Real-IP $remote_addr;
        client_max_body_size 15M;
    }

# link websockets to ws-proxy
    location /api/v1/stomp {
{% if not iot.wsproxy.external.enable %}
        proxy_pass http://wsproxy:8075$request_uri;
{% else %}
        proxy_pass http://{{ iot.wsproxy.external.host }}:{{ iot.wsproxy.external.port }}$request_uri;
{% endif %}
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header Host $http_host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Real-IP $remote_addr;
    }

    location /api/v1/event_ws {
{% if not iot.wsproxy.external.enable %}
        proxy_pass http://wsproxy:8075$request_uri;
{% else %}
        proxy_pass http://{{ iot.wsproxy.external.host }}:{{ iot.wsproxy.external.port }}$request_uri;
{% endif %}
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header Host $http_host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Real-IP $remote_addr;
    }

{% if iot.core.video.evi.url != '' and iot.core.video.evi.apiKey != '' %}
  #--------------------- Proxy auth for evi admin --------------------------------
    location ~ ^/evi/(?<suffix>.*) {
        auth_request /auth;
        proxy_pass {{ iot.core.video.evi.url }}/$suffix?$args;
        proxy_set_header X-Vsaas-Api-Key {{ iot.core.video.evi.apiKey }};
    }

    location = /auth {
        if ($request_method = OPTIONS) {
            return 200;
        }

        internal;
        proxy_pass https://authorization-server:{{ iot.authorization.port.ssl.map }}/api/v1/authorization/verify?roleId=admin;
        proxy_http_version 1.1;
        proxy_pass_request_body off;
        proxy_set_header Content-Length "";
    }
  #-------------------------------------------------------------------------------
{% endif %}

    # firmware files for rule upload
    # TODO delete after http://red.eltex.loc/issues/352170
    location /api/v1/firmware/rule/upload {
        proxy_pass http://core:{{ iot.core.port.map }}$request_uri;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header Host $http_host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Real-IP $remote_addr;
        client_max_body_size 256M;
    }

    # firmware files for direct upload
    location /api/v1/files/upload {
        proxy_pass http://core:{{ iot.core.port.map }}$request_uri;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header Host $http_host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Real-IP $remote_addr;
        client_max_body_size 40M;
    }

    location /api {
{% if iot.web.nginx.rateLimit.enable %}
        limit_req zone=api_perip burst=100 nodelay;
{% endif %}
        proxy_pass http://core:{{ iot.core.port.map }}$request_uri;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header Host $http_host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Real-IP $remote_addr;
        client_max_body_size 20M;
    }

    location /stomp {
        proxy_pass http://core:{{ iot.core.port.map }}$request_uri;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header Host $http_host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Real-IP $remote_addr;
    }

    location /.well-known/apple-app-site-association {
        add_header Content-Type application/json;
        default_type application/json;
        try_files $uri /.well-known/apple-app-site-association.json;
    }

    location /.well-known/assetlinks.json {
        add_header Content-Type application/json;
        default_type application/json;
        try_files $uri /.well-known/assetlinks.json;
    }

    location /nginx_status {
    stub_status on;
    access_log off;
    allow 172.16.0.0/12;
    deny all;
    }

    location /authorization-server/actuator/prometheus {
        proxy_pass https://authorization-server:{{ iot.authorization.port.ssl.map }}/api/v1/actuator/prometheus;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header Host $http_host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Real-IP $remote_addr;
        client_max_body_size 20M;
    }

    location /broker/actuator/prometheus {
        proxy_pass http://{{ iot.broker.external.host if iot.broker.external.enable else 'broker' }}:{{ iot.broker.internal.port.map }}/actuator/prometheus;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header Host $http_host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Real-IP $remote_addr;
        client_max_body_size 20M;
    }
}

{% include web_additional_server_blocks ignore missing %}

В данный файл требуется внести следующие изменения: