Skip to content

Введение ​

Данная инструкция описывает установку в среде Docker комбинированного экземпляра, в котором в одном контейнере работают два компонента:

  • ЛМ ЧЗ (Локальный Модуль «Честный знак») — работа с маркированными товарами, проверки оффлайн по разрешительному режиму;
  • Контроллер ЛМ ЧЗ (от "АО "ЕСП""") — шлюз для кассы, предоставляющий REST и gRPC (TLS) интерфейсы.

Инструкция описывает только комбинированный образ registry.itida.ru/regime-esm. Установка «голого» ЛМ ЧЗ (без контроллера), требования к системе, порядок установки Docker и Docker Compose, а также общие принципы работы с архивом преднастроенных папок подробно описаны в отдельной статье:

ИНФОРМАЦИЯ

Базовая установка ЛМ ЧЗ, требования к ОС и установка Docker: Установка Локального Модуля Честного знака в docker

ВНИМАНИЕ

Важно: Инструкция предполагает, что Docker и Docker Compose уже установлены и вы обладаете базовыми навыками работы с ними. Порядок установки Docker — см. статью по ссылке выше.

Состав комбинированного образа ​

Образ registry.itida.ru/regime-esm содержит внутри одного контейнера два компонента, которые стартуют совместно и взаимодействуют между собой по localhost:

КомпонентНазначениеПорт внутри контейнера
ЛМ ЧЗ (regime / yenisei)Локальный модуль «Честный знак», внутренний REST и веб-интерфейс, БД CouchDB5995
Контроллер ЛМ (lmcontroller)REST и gRPC (TLS) для кассы5063 (REST), 50063 (gRPC)

Пример используемой версии образа:

yml
image: registry.itida.ru/regime-esm:2.6.1-889_1.6.4.0

где 2.6.1-889 — версия ЛМ ЧЗ, 1.6.4.0 — версия Контроллера ЛМ.

Структура каталогов экземпляра ​

Структура каталогов экземпляра полностью совпадает со структурой «голого» ЛМ ЧЗ (config, data, logs), но дополняется каталогом esp для Контроллера — он добавляется рядом, существующие каталоги ЛМ ЧЗ не меняются. Это упрощает переход с уже установленного «голого» ЛМ ЧЗ (см. раздел «Переход с голого образа ЛМ ЧЗ»).

regime-esm/                   # рабочий каталог (содержимое архива)
├── docker-compose.yaml
├── regime1/                  # экземпляр 1
│   ├── config/               # → /opt/regime/etc        (конфиг ЛМ ЧЗ: ext.ini)
│   │   └── ext.ini           #   пустой шаблон из архива
│   ├── data/                 # → /opt/yenisei/data      (база CouchDB; при первом старте пустой)
│   ├── logs/                 # → /var/log/regime        (логи ЛМ ЧЗ)
│   └── esp/                  #   каталог Контроллера ЛМ (новое относительно голого образа)
│       ├── config/           # → /etc/esp/lmcontroller  (config.yml + сертификаты; пустой)
│       └── logs/             # → /var/log/esp           (логи Контроллера)
└── regime2/                  # экземпляр 2 — аналогичная структура

ВНИМАНИЕ

Важно: каталоги data и esp/config создаются пустыми. База ЛМ ЧЗ инициализируется автоматически при первом старте, а Контроллер сам сгенерирует config.yml и набор сертификатов (ca.crt, ca.pem, server.crt, server.pem) в esp/config. Файл же config/ext.ini присутствовать обязан — без него ЛМ ЧЗ не запустится.

Подготовка каталога нового экземпляра ​

Подготовить каталоги экземпляров можно двумя способами: использовать готовый архив (рекомендуется) или создать структуру вручную.

Способ 1. Готовый архив (рекомендуется) ​

Скачайте архив с преднастроенными папками и docker-compose для двух совмещённых экземпляров и распакуйте его в каталог на жёстком диске (например на диск D:).

В архиве уже подготовлено:

  • docker-compose.yaml с двумя сервисами lmcz-esm1 и lmcz-esm2: образ 2.6.1-889_1.6.4.0, тома и порты по схеме для локального подключения (Контроллеры на 127.0.0.1 и 127.0.0.2, см. «Развертывание нескольких экземпляров на одном хосте»);
  • каталоги regime1 и regime2 со структурой config, data, logs и каталогом esp/{config,logs};
  • пустой шаблон ext.ini в config каждого экземпляра.

После распаковки достаточно при необходимости отредактировать порты/имена и перейти к запуску (раздел «Первый запуск»). После первого запуска добавьте адрес 127.0.0.2 в сертификат Контроллера второго экземпляра (раздел «Адрес экземпляра в сертификате Контроллера»).

Способ 2. Создание структуры вручную ​

  1. Создайте рабочий каталог для развёртывания (например D:\regime).

  2. Создайте структуру каталогов экземпляра. В PowerShell:

powershell
$base = "regime1"
New-Item -ItemType Directory -Force -Path `
  "$base\config", "$base\data", "$base\logs", `
  "$base\esp\config", "$base\esp\logs" | Out-Null
  1. Положите пустой шаблон ext.ini в regime1\config\.

Пустой конфиг ЛМ ЧЗ (ext.ini) ​

ЛМ ЧЗ не запустится без файла ext.ini. В готовом архиве он уже есть; при ручной подготовке используйте тот же пустой шаблон, что и для «голого» ЛМ ЧЗ. Содержимое шаблона:

ini
[api]
login = admin
password = admin

[remote]
service_url = https://rsapi.crpt.ru
proxy_host =
proxy_port =
proxy_user =
proxy_password =

Скопируйте файл ext.ini из архива в regime1\config\ext.ini.

ИНФОРМАЦИЯ

ЛМ ЧЗ при первом старте сам дополнит ext.ini остальными параметрами (идентификатор экземпляра, реквизиты БД и т.п.) и зашифрует логины и пароли. Вручную дописывать ничего не нужно — окончательная настройка и активация выполняются после старта (см. раздел «Инициализация ЛМ ЧЗ»).

Получение образа ​

Перед запуском образ registry.itida.ru/regime-esm:<версия> должен присутствовать на хосте. Возможны два варианта.

Вариант А. Загрузка из реестра (основной) ​

Если хост имеет доступ к registry.itida.ru, образ подтянется автоматически при docker compose up -d. Можно загрузить заранее:

bash
docker pull registry.itida.ru/regime-esm:2.6.1-889_1.6.4.0

Вариант Б. Загрузка из готового файла (при региональных блокировках / белых списках) ​

Если целевой хост не может скачать образ из реестра (региональные блокировки интернета, белые списки, закрытый периметр), используйте заранее подготовленный файл образа — отдельный ПК с доступом к реестру при этом не требуется.

Шаг 1. Скачайте файл образа нужной версии:

Версия (ЛМ ЧЗ + Контроллер)Файл образа
2.5.1-721_1.6.3.0Скачать (.tgz, ~180 МБ)
2.6.1-889_1.6.4.0Скачать (.tgz, ~190 МБ)

Шаг 2. Загрузите образ из скачанного файла на целевом хосте (Docker сам распакует gzip):

bash
docker load -i regime-esm261-8891640.tgz

Шаг 3. Проверьте, что образ появился и тег совпадает с указанным в docker-compose.yaml:

bash
docker images

ВНИМАНИЕ

Тег загруженного образа обязан точно совпадать со значением image: в docker-compose.yaml, иначе при запуске Compose снова попытается скачать образ из реестра. При необходимости переименуйте образ:

bash
docker tag <загруженный_image_id> registry.itida.ru/regime-esm:2.6.1-889_1.6.4.0

Как самостоятельно сделать файл образа ​

Если нужного файла нет в списке (например, для новой версии образа), его можно подготовить на любой машине с доступом к реестру:

bash
docker pull registry.itida.ru/regime-esm:2.6.1-889_1.6.4.0
docker save registry.itida.ru/regime-esm:2.6.1-889_1.6.4.0 | gzip > regime-esm_2.6.1-889_1.6.4.0.tgz

Полученный файл regime-esm_<версия>.tgz переносится на целевой хост и загружается командой docker load -i (шаги 2–3 выше).

Файл docker-compose.yaml для одного экземпляра ​

Создайте в рабочем каталоге файл docker-compose.yaml:

yml
services:
  lmcz-esm1:
    image: registry.itida.ru/regime-esm:2.6.1-889_1.6.4.0
    container_name: lmcz-esm1
    restart: always
    ports:
      - "5997:5995"     # ЛМ ЧЗ (regime), внутренний REST / веб-интерфейс
      - "5063:5063"     # Контроллер ЛМ, REST (порт для кассы)
      - "50063:50063"   # Контроллер ЛМ, gRPC (TLS, основной порт для кассы)
    volumes:
      - ./regime1/config:/opt/regime/etc           # конфиг ЛМ ЧЗ (ext.ini)
      - ./regime1/data:/opt/yenisei/data           # база данных ЛМ ЧЗ (CouchDB/yenisei)
      - ./regime1/logs:/var/log/regime             # логи ЛМ ЧЗ
      - ./regime1/esp/config:/etc/esp/lmcontroller # config.yml + сертификаты Контроллера
      - ./regime1/esp/logs:/var/log/esp            # логи Контроллера

Порты указываются в формате хост:контейнер:

  • 5997:5995 — веб-интерфейс/REST ЛМ ЧЗ, доступен по http://<адрес_хоста>:5997;
  • 5063:5063 — REST Контроллера (к нему обращается касса);
  • 50063:50063 — gRPC Контроллера по TLS (основной канал кассы).

Внутренние порты контейнера (правая часть: 5995, 5063, 50063) менять не нужно.

ИНФОРМАЦИЯ

Внутри контейнера localhost и 127.0.0.1 указывают на сам контейнер. Контроллер обращается к ЛМ ЧЗ по localhost:5995 внутри своего контейнера, поэтому одинаковые внутренние порты у разных экземпляров друг другу не мешают.

Развертывание нескольких экземпляров на одном хосте ​

На одном хосте можно поднять несколько комбинированных экземпляров. Для каждого экземпляра нужно сделать уникальными:

  1. container_name — имя контейнера;
  2. адрес хоста, на котором публикуются порты Контроллера (5063 и 50063), — см. ниже;
  3. host-порт веб-интерфейса ЛМ ЧЗ (5997, 5998, …);
  4. каталоги томов — отдельный каталог под каждый экземпляр.

ОСТОРОЖНО

Каталоги томов не должны совпадать между экземплярами. Если два контейнера смонтируют один и тот же data, config или esp/config, два ЛМ ЧЗ будут писать в одну базу и работать с одним ext.ini (одинаковые instance_id, ИНН и учётные данные ЦРПТ), а Контроллеры — с одними сертификатами. Это приводит к порче базы и путанице экземпляров. При копировании блока сервиса в docker-compose.yaml обязательно замените пути во всех пяти томах.

Почему нельзя разнести экземпляры по разным портам ​

ЕСМ (модуль управления ТС ПИоТ) подключается к Контроллеру ЛМ в два этапа:

  1. по REST запрашивает сведения о сервисе и сертификат УЦ Контроллера (/api/v1/service-info, /api/v1/cert);
  2. по gRPC (TLS) подключается к Контроллеру, проверяя его сертификат полученным на шаге 1 сертификатом УЦ.

В утилите ЕСМ задаются только адрес и gRPC-порт Контроллера. REST-порт не настраивается: ЕСМ всегда обращается на порт 5063 по указанному адресу. Параметр ldbControl.RESTPort в C:\ProgramData\ESP\ESM\um\config_<id>.yml ЕСМ перезаписывает значением 5063 при переподключении к Контроллеру, поэтому правка этого файла не помогает.

Если опубликовать второй экземпляр на портах 5064/50064, ЕСМ возьмёт сертификат УЦ у первого экземпляра (REST 5063), а по gRPC пойдёт во второй. Проверка TLS не пройдёт, и ЕСМ не увидит Контроллер (см. «Типовые проблемы»).

Поэтому каждый экземпляр публикуется на стандартных портах 5063 и 50063, но на своём IP-адресе хоста.

Схема для локального подключения ​

Схема с несколькими экземплярами в Docker предназначена для локального подключения: ЕСМ установлена на том же компьютере, что и Docker. Каждому экземпляру назначается свой адрес из диапазона 127.0.0.0/8 — в Windows весь этот диапазон относится к локальной петле, дополнительно ничего настраивать не нужно.

ЭкземплярКаталогcontainer_nameЛМ ЧЗ (web)Контроллер RESTКонтроллер gRPCПодключение в ЕСМ
1regime1lmcz-esm15997:5995127.0.0.1:5063:5063127.0.0.1:50063:50063127.0.0.1, порт 50063
2regime2lmcz-esm25998:5995127.0.0.2:5063:5063127.0.0.2:50063:50063127.0.0.2, порт 50063
3regime3lmcz-esm35999:5995127.0.0.3:5063:5063127.0.0.3:50063:50063127.0.0.3, порт 50063

ВНИМАНИЕ

Порты Контроллера у всех экземпляров привязывайте к конкретному адресу, в том числе у первого (127.0.0.1:…). Если один экземпляр опубликован на всех интерфейсах ("5063:5063", то есть 0.0.0.0), Docker не даст другому занять тот же порт на отдельном адресе.

ИНФОРМАЦИЯ

Если Контроллер нужен кассам или ЕСМ с других компьютеров сети и экземпляров несколько, ЛМ ЧЗ и Контроллер устанавливаются не в Docker. Схема с одним экземпляром (раздел «Файл docker-compose.yaml для одного экземпляра») может публиковать порты на всех интерфейсах.

Пример docker-compose.yaml на два экземпляра ​

yml
services:
  lmcz-esm1:
    image: registry.itida.ru/regime-esm:2.6.1-889_1.6.4.0
    container_name: lmcz-esm1
    restart: always
    ports:
      - "5997:5995"
      - "127.0.0.1:5063:5063"
      - "127.0.0.1:50063:50063"
    volumes:
      - ./regime1/config:/opt/regime/etc
      - ./regime1/data:/opt/yenisei/data
      - ./regime1/logs:/var/log/regime
      - ./regime1/esp/config:/etc/esp/lmcontroller
      - ./regime1/esp/logs:/var/log/esp

  lmcz-esm2:
    image: registry.itida.ru/regime-esm:2.6.1-889_1.6.4.0
    container_name: lmcz-esm2
    restart: always
    ports:
      - "5998:5995"
      - "127.0.0.2:5063:5063"
      - "127.0.0.2:50063:50063"
    volumes:
      - ./regime2/config:/opt/regime/etc
      - ./regime2/data:/opt/yenisei/data
      - ./regime2/logs:/var/log/regime
      - ./regime2/esp/config:/etc/esp/lmcontroller
      - ./regime2/esp/logs:/var/log/esp

ИНФОРМАЦИЯ

Для каждого экземпляра заранее создайте свой каталог (regime1, regime2, …) по структуре из раздела «Структура каталогов экземпляра» и положите в config/ext.ini пустой шаблон.

Адрес экземпляра в сертификате Контроллера ​

Контроллер выпускает серверный сертификат на localhost, 127.0.0.1, ::1 и внутренний адрес контейнера. Для первого экземпляра (127.0.0.1) этого достаточно. Для второго и следующих экземпляров адрес 127.0.0.2, 127.0.0.3, … нужно добавить в сертификат, иначе ЕСМ отвергнет его при подключении.

  1. Запустите экземпляр, чтобы Контроллер сгенерировал esp/config/config.yml и сертификаты.

  2. В esp/config/config.yml этого экземпляра укажите его адрес в секции certificate:

    yml
        certificate:
            hosts: ["127.0.0.2"]
  3. Перезапустите контейнер:

    bash
    docker compose restart lmcz-esm2

При старте Контроллер перевыпустит server.crt и server.pem с новым адресом. Сертификат УЦ (ca.crt, ca.pem) при этом не меняется. Проверить адреса в сертификате можно командой:

bash
openssl s_client -connect 127.0.0.2:50063 </dev/null 2>/dev/null | openssl x509 -noout -ext subjectAltName

В выводе должен быть IP Address:127.0.0.2.

Переход с голого образа ЛМ ЧЗ ​

Если у вас уже развёрнут «голый» ЛМ ЧЗ (по базовой инструкции), переход на совмещённый образ выполняется без перестроения каталогов — структура config/data/logs сохраняется как есть, к каждому экземпляру лишь добавляется каталог esp, а в docker-compose.yaml меняется образ и добавляются порты и тома Контроллера.

ВНИМАНИЕ

Перед началом сделайте резервную копию всего рабочего каталога (regime1, regime2 с их config/data/logs). В них хранится активированный ЛМ ЧЗ и база данных.

Шаг 1. Остановите текущие контейнеры в каталоге с docker-compose.yaml:

bash
docker compose down

Шаг 2. Из готового архива скопируйте каталог esp (с подкаталогами config и logs) в каждый каталог экземпляра — рядом с существующими config/data/logs:

regime1\esp\config
regime1\esp\logs
regime2\esp\config
regime2\esp\logs

Каталоги config, data, logs не трогайте — они остаются с вашими данными.

Шаг 3. Отредактируйте docker-compose.yaml для каждого экземпляра:

  • замените образ на совмещённый:
    yml
    image: registry.itida.ru/regime-esm:2.6.1-889_1.6.4.0
  • добавьте проброс портов Контроллера. При нескольких экземплярах каждому нужен свой адрес хоста, порты остаются 5063 и 50063 (см. «Схема для локального подключения»):
    yml
        - "127.0.0.1:5063:5063"
        - "127.0.0.1:50063:50063"
  • добавьте два тома Контроллера:
    yml
        - ./regime1/esp/config:/etc/esp/lmcontroller
        - ./regime1/esp/logs:/var/log/esp

Порт и тома ЛМ ЧЗ (config/data/logs) оставьте без изменений.

Шаг 4. Получите совмещённый образ (раздел «Получение образа») и запустите контейнеры:

bash
docker compose up -d

При старте Контроллер сгенерирует config.yml и сертификаты в esp/config, а ЛМ ЧЗ продолжит работать с уже имеющейся базой и настройками.

Первый запуск ​

  1. Откройте командную строку или PowerShell и перейдите в каталог с docker-compose.yaml:
cmd
cd D:\regime-esm
  1. Убедитесь, что образ доступен (раздел «Получение образа») и каталоги подготовлены.

  2. Запустите развёртывание и дождитесь его завершения:

bash
docker compose up -d

Что произойдёт при первом старте:

  • ЛМ ЧЗ считает пустой ext.ini, инициализирует базу CouchDB в data, дозаполнит ext.ini и зашифрует логины/пароли.
  • Контроллер сгенерирует config.yml и сертификаты в esp/config, поднимет REST (5063) и gRPC (50063). До настройки ЛМ ЧЗ статус будет not_configured — это нормально.

После успешного развёртывания запущенные контейнеры отобразятся в Docker Desktop, а в каталоге regime1/esp/config/ появятся config.yml и сертификаты.

Инициализация ЛМ ЧЗ ​

Окончательная настройка и инициализация ЛМ ЧЗ выполняется экземпляром ТС ПИоТ. Оркестратор ЕСМ опрашивает контроллер ЛМ ЧЗ, тот в свою очередь получает статус ЛМ ЧЗ и при статусе "Не сконфигурирован" сам выполняет метод SafeInit, которая и запускает процедуру инициализации ЛМ ЧЗ.

В утилите ЕСМ в настройках подключения к ЛМ укажите адрес экземпляра и gRPC-порт 50063: для одного экземпляра — адрес хоста, для нескольких — адрес из таблицы «Схема для локального подключения» (127.0.0.1, 127.0.0.2, …). REST-порт в утилите не задаётся, ЕСМ всегда использует 5063 на том же адресе.

Логин/пароль по умолчанию — admin / admin. Дальнейшее подключение к Айтида iMark выполняются по общей инструкции: Подключение локального модуля к Айтида iMark.

ИНФОРМАЦИЯ

Для добавления кассы (ККТ) к экземпляру ЕСМ/ТС ПИоТ предусмотрена отдельная GUI-утилита — см. Утилита добавления ККТ к ЕСМ/ТС ПИоТ.

Проверка работоспособности ​

bash
# Статус контейнеров
docker compose ps

# Логи конкретного экземпляра
docker compose logs -f lmcz-esm1

Логи также доступны в смонтированных каталогах на хосте:

  • ЛМ ЧЗ: regime1/logs/regime.log, yenisei.log;
  • Контроллер: regime1/esp/logs/lmcontroller/lmcontroller.log.

Признаки нормального старта в логе Контроллера:

Сервер REST слушает порт 5063
Сервер gRPC v2.1 слушает порт 50063
Статус ЛМ ЧЗ 2.0 получен: версия=2.6.1-889, статус=not_configured, режим=active

Обновление ​

Для обновления версии измените тег образа в image: файла docker-compose.yaml на новый, затем выполните в каталоге с compose-файлом:

bash
docker compose pull     # либо загрузка готового файла образа — см. «Получение образа», вариант Б
docker compose stop
docker compose up -d

ИНФОРМАЦИЯ

При закрытом реестре вместо docker compose pull загрузите новый образ из готового файла (docker load), как описано в разделе «Получение образа», вариант Б.

Резервное копирование ​

Состояние экземпляра целиком хранится в его каталоге. Для бэкапа при остановленном контейнере сохраните каталог экземпляра:

bash
docker compose stop lmcz-esm1
# скопировать каталог regime1 целиком (config, data, esp/config)
docker compose start lmcz-esm1

Критично важны для восстановления:

  • config/ext.ini — настроенный и зашифрованный конфиг ЛМ ЧЗ;
  • data — база данных ЛМ ЧЗ;
  • esp/config — config.yml и сертификаты Контроллера.

Типовые проблемы ​

СимптомПричина и решение
Контейнер ЛМ ЧЗ не стартует / падает сразуОтсутствует ext.ini в config. Положите пустой шаблон.
docker compose up пытается скачать образ и падает по сетиНет доступа к registry.itida.ru. Загрузите образ из готового файла (раздел «Получение образа», вариант Б) и проверьте совпадение тега.
После docker load Compose всё равно тянет образ из реестраТег загруженного образа не совпадает с image: в compose. Переименуйте через docker tag.
Порт занят (bind: address already in use, port is already allocated)Конфликт host-портов между экземплярами или с другими службами. Порты Контроллера разносите по адресам (127.0.0.1, 127.0.0.2, …), а не по номерам; не публикуйте один экземпляр на 0.0.0.0, если другой занимает тот же порт на отдельном адресе.
При пересоздании контейнеров: ports are not available … Only one usage of each socket addressDocker Desktop ещё не освободил порт после остановки старого контейнера. Повторите docker compose up -d.
В логе ЕСМ (C:\ProgramData\ESP\ESM\um\log\esm-cm_<id>.log): tls: failed to verify certificate: x509: certificate signed by unknown authority … "ESP LM Controller CA", затем error 2025: ЛМ контроллер не найденREST (5063) и gRPC ведут в разные Контроллеры: ЕСМ взяла сертификат УЦ у одного экземпляра, а по gRPC подключилась к другому. Обычно так бывает, если второй экземпляр опубликован на других номерах портов (5064/50064). Опубликуйте его на 5063/50063 на отдельном адресе и укажите этот адрес в ЕСМ.
В логе ЕСМ ошибка TLS с адресом экземпляра (certificate is valid for … not 127.0.0.2)Адрес экземпляра не добавлен в сертификат Контроллера. Укажите его в certificate.hosts файла esp/config/config.yml и перезапустите контейнер (раздел «Адрес экземпляра в сертификате Контроллера»).
Запросы ЕСМ приходят не в тот экземплярСверьте адрес в утилите ЕСМ с привязкой портов в docker-compose.yaml. Куда реально приходят запросы, видно по логам Контроллеров (esp/logs/lmcontroller/lmcontroller.log, строки /api/v1/service-info и /api/v1/cert). Логи ЕСМ — в C:\ProgramData\ESP\ESM.
Статус not_configured в логахНормально до инициализации ЛМ ЧЗ со стороны ТС ПИоТ.
Каталог esp/config пуст, сертификаты не появилисьКонтроллер не стартовал. Проверьте esp/logs/lmcontroller/lmcontroller.log и что каталог esp/config смонтирован и доступен на запись.