Установка
Система "Графиня" разворачивается в Docker-контейнерах при помощи Docker Compose. В качестве СУБД используется MongoDB. Для скачивания docker-образов компонентов Графини необходимо воспользоваться учётной записью в репозитории Лаборатории Числитель.
После установки веб-интерфейс будет доступен по адресу http://<HOST> или http://<HOST>:<PORT>, в зависимости от настроенного порта frontend.
Данные для авторизации в веб-интерфейсе "Графини" по умолчанию: Логин: admin / Пароль: 123456
На первом входе система запросит смену пароля.
Предварительные требования
- Установленные Docker и Docker Compose.
- Доступ к приватному реестру образов
registry.pult.chislitellab.ru:8124. - Если используются модуль оповещений или модуль РСМ, также нужен доступ к реестру
registry.pult.chislitellab.ru:8126. - Пользователь с правами на скачивание образов из указанных реестров.
Шаг 1: Подготовка окружения
Для быстрой подготовки файлов можно воспользоваться Конструктором развёртывания Графини. Он генерирует:
docker-compose.yml.env.env_mongo.env_backend.env_frontend.env_notificationREADME.mdс краткой сводкой по выбранной конфигурации
Ниже приведён расширенный пример для версии 2026H1.1.1 "Салон": кеширование включено, модуль оповещений и модуль РСМ включены, а в docker-compose.yml добавлены все плагины, поддерживаемые текущим конструктором установки.
- Создайте рабочую директорию для проекта:
mkdir grafinya && cd grafinya
- Создайте файл
docker-compose.ymlсо следующим содержимым:
services:
mongo:
image: registry.pult.chislitellab.ru:8124/portal/database-app:2026H1.1.1
env_file: .env_mongo
restart: unless-stopped
command:
- mongod
- --replSet
- rs0
- --bind_ip_all
- --keyFile
- /run/secrets/mongo-replica-key
secrets:
- source: mongo-replica-key
target: mongo-replica-key
uid: "999"
gid: "999"
mode: 0400
healthcheck:
test:
[
"CMD-SHELL",
'mongosh --quiet -u "$$MONGO_INITDB_ROOT_USERNAME" -p "$$MONGO_INITDB_ROOT_PASSWORD" --authenticationDatabase admin --eval "db.adminCommand({ ping: 1 }).ok === 1 ? quit(0) : quit(1)"',
]
interval: 5s
timeout: 5s
retries: 12
start_period: 10s
ports:
- "27017:27017"
volumes:
- mongo-data:/data/db
networks:
- grafinya
mongo-rs-init:
image: registry.pult.chislitellab.ru:8124/portal/database-app:2026H1.1.1
env_file: .env_mongo
entrypoint: ["/bin/sh", "/usr/local/bin/init-replica.sh"]
restart: "no"
depends_on:
mongo:
condition: service_healthy
networks:
- grafinya
tarantool-cache:
image: registry.pult.chislitellab.ru:8124/portal/tarantool:2.11
restart: unless-stopped
expose:
- "3301"
networks:
- grafinya
backend:
image: registry.pult.chislitellab.ru:8124/portal/backend-app:2026H1.1.1
restart: unless-stopped
command: node dist/server.js
healthcheck:
test: ["CMD", "node", "-e", "const url = new URL(process.env.HEALTHCHECK_URL || 'http://127.0.0.1:5000/healthz'); const client = url.protocol === 'https:' ? require('https') : require('http'); const req = client.get(url, (res) => process.exit(res.statusCode === 200 ? 0 : 1)); req.on('error', () => process.exit(1)); req.setTimeout(4000, () => { req.destroy(); process.exit(1); });"]
interval: 30s
timeout: 5s
retries: 3
start_period: 30s
ports:
- "5000:5000"
env_file: .env_backend
environment:
SECURITY_LOG_FILE_PATH: ${SECURITY_LOG_FILE_PATH:-/app-data/security/security.log}
volumes:
- security-log-data:/app-data/security
depends_on:
mongo-rs-init:
condition: service_completed_successfully
tarantool-cache:
condition: service_started
networks:
- grafinya
cache-worker:
image: registry.pult.chislitellab.ru:8124/portal/backend-app:2026H1.1.1
restart: unless-stopped
env_file: .env_backend
command: node dist/workers/cacheWorker.js
healthcheck:
test: ["CMD-SHELL", "ps | grep -Eq '[c]acheWorker\\.(ts|js)'"]
interval: 30s
timeout: 5s
retries: 3
start_period: 30s
depends_on:
mongo-rs-init:
condition: service_completed_successfully
tarantool-cache:
condition: service_started
backend:
condition: service_healthy
networks:
- grafinya
frontend:
image: registry.pult.chislitellab.ru:8124/portal/frontend-app:2026H1.1.1
restart: unless-stopped
env_file: .env_frontend
ports:
- "80:80"
networks:
- grafinya
prometheus-plugin:
image: registry.pult.chislitellab.ru:8124/portal/plugins/prometheus:1.3.5
restart: unless-stopped
ports:
- "8080:8080"
networks:
- grafinya
pult-plugin:
image: registry.pult.chislitellab.ru:8124/portal/plugins/pult:1.3.5
restart: unless-stopped
ports:
- "8081:8080"
networks:
- grafinya
csv-plugin:
image: registry.pult.chislitellab.ru:8124/portal/plugins/csv-plugin:1.3.5
restart: unless-stopped
ports:
- "8082:8080"
networks:
- grafinya
postgres-plugin:
image: registry.pult.chislitellab.ru:8124/portal/plugins/postgres-plugin:1.3.5
restart: unless-stopped
ports:
- "8083:8080"
networks:
- grafinya
json-plugin:
image: registry.pult.chislitellab.ru:8124/portal/plugins/json-plugin:1.3.5
restart: unless-stopped
ports:
- "8084:8080"
networks:
- grafinya
gitlab-plugin:
image: registry.pult.chislitellab.ru:8124/portal/plugins/gitlab-plugin:1.3.5
restart: unless-stopped
ports:
- "8085:8080"
networks:
- grafinya
elasticsearch-plugin:
image: registry.pult.chislitellab.ru:8124/portal/plugins/elasticsearch-plugin:1.3.5
restart: unless-stopped
ports:
- "8086:8080"
networks:
- grafinya
clickhouse-plugin:
image: registry.pult.chislitellab.ru:8124/portal/plugins/clickhouse-plugin:1.3.5
restart: unless-stopped
ports:
- "8087:8080"
networks:
- grafinya
alerting-worker:
image: registry.pult.chislitellab.ru:8124/portal/backend-app:2026H1.1.1
restart: unless-stopped
env_file: .env_backend
command: node dist/workers/alertingWorker.js
healthcheck:
test: ["CMD-SHELL", "ps | grep -Eq '[a]lertingWorker\\.(ts|js)'"]
interval: 30s
timeout: 5s
retries: 3
start_period: 30s
depends_on:
mongo-rs-init:
condition: service_completed_successfully
backend:
condition: service_healthy
networks:
- grafinya
notification-service:
image: registry.pult.chislitellab.ru:8126/portal/services/notification-service:2026H1.1.1
restart: unless-stopped
env_file: .env_notification
expose:
- "8080"
depends_on:
mongo-rs-init:
condition: service_completed_successfully
networks:
- grafinya
rsm-module-api:
image: registry.pult.chislitellab.ru:8126/portal/modules/rsm-module-api:1.3.5
restart: unless-stopped
environment:
FRONTEND_HOST: "http://<HOST_IP>:8202"
expose:
- "8080"
networks:
- grafinya
rsm-module-ui:
image: registry.pult.chislitellab.ru:8126/portal/modules/rsm-module-ui:1.3.5
restart: unless-stopped
environment:
ALLOWED_ORIGIN: "http://<HOST_IP>"
ports:
- "8202:3000"
networks:
- grafinya
volumes:
mongo-data:
security-log-data:
networks:
grafinya:
driver: bridge
secrets:
mongo-replica-key:
environment: MONGO_REPLICA_SET_KEY
Параметр FRONTEND_HOST у сервиса rsm-module-api должен указывать на внешний URL rsm-module-ui, доступный из браузера пользователя. По умолчанию это http://<HOST_IP>:8202, но при необходимости укажите другой домен или порт. Тот же адрес указывается в RSM_MODULE_FRONTEND_HOST в .env_backend — значения должны совпадать.
Порт rsm-module-ui (по умолчанию 8202) нужно открыть в firewall. Портал и API работают через один origin: nginx фронтенда сам проксирует /api на backend, поэтому наружу достаточно порта фронтенда. Бандл РСМ — единственный ресурс, за которым браузер идёт на отдельный адрес и порт. Если адрес не резолвится с рабочего места пользователя или порт закрыт, страницы РСМ не откроются, а в консоли браузера будет ERR_CONNECTION_TIMED_OUT на /module/rsm/module.js.
Сервис rsm-module-api наружу не публикуется: браузер обращается к API модуля через прокси backend (/api/v1/modules/:id/proxy), а сам backend — по имени сервиса в docker-сети.
В образах 2026H1.1 переменная RSM_MODULE_FRONTEND_HOST применяется только при создании записи модуля в базе. При обновлении поверх существующей базы значение из .env_backend игнорируется, и модуль остаётся с прежним адресом. Проверьте адрес модуля в разделе «Модули» портала и при необходимости исправьте его вручную. В последующих релизах значение применяется при каждом старте backend и перекрывает правки в интерфейсе.
В примере выше сервисы alerting-worker и notification-service относятся к модулю оповещений. Если модуль не нужен, оба сервиса можно не описывать — остальная конфигурация от этого не меняется. Сервисы mongo и mongo-rs-init нужны всегда.
- Создайте необходимые
.env-файлы.
MONGO_INITDB_ROOT_USERNAME=<DB_LOGIN>
MONGO_INITDB_ROOT_PASSWORD=<DB_PASSWORD>
MONGO_INITDB_DATABASE=grafinya
Обязательно укажите свои DB_LOGIN и DB_PASSWORD, иначе система не запустится корректно. Пример:
MONGO_INITDB_ROOT_USERNAME=admin
MONGO_INITDB_ROOT_PASSWORD=123456
MONGO_INITDB_DATABASE=grafinya
MONGO_REPLICA_SET_KEY=<MONGO_REPLICA_SET_KEY>
MONGO_REPLICA_SET_KEY — ключ, которым узлы реплика-сета аутентифицируют друг друга. MongoDB запускается с этим ключом, без него контейнер mongo не стартует.
Этот файл отличается от остальных: его читает сам docker compose, а не контейнеры. Значение попадает в секцию secrets и оттуда — в файл /run/secrets/mongo-replica-key внутри контейнера MongoDB. Через env_file ключ передать нельзя: env_file наполняет окружение контейнера, а секция secrets берёт значения из окружения самого docker compose. Поэтому команды docker compose выполняйте из каталога, где лежит .env.
Сгенерировать значение:
openssl rand -base64 756 | tr -d '[:space:]'
Ключ задаётся один раз при развёртывании и дальше не меняется: смена ключа на заполненной базе потребует перенастройки реплика-сета.
c. .env_backend:# --- Подключение к MongoDB ---
# replicaSet=rs0 — часть базовой конфигурации, оставляйте параметр всегда
MONGO_URI=mongodb://<DB_LOGIN>:<DB_PASSWORD>@mongo:27017/grafinya?authSource=admin&replicaSet=rs0
# --- Express / runtime ---
PORT=5000
# --- JWT ---
JWT_SECRET=<JWT_SECRET>
JWT_REFRESH_SECRET=<JWT_REFRESH_SECRET>
EXPIRES_TOKEN=24h
EXPIRES_REFRESH_TOKEN=7d
# --- CORS / origins ---
ALLOWED_ORIGIN=http://<HOST>
# --- Сессия ---
AUTH_COOKIE_MODE=dual
# --- Безопасность / служебные ---
INACTIVE_USER_DEACTIVATION_CHECK_INTERVAL_MINUTES=60
ADMIN_MAX_CONCURRENT_SESSIONS=2
SECURITY_LOG_FILE_PATH=/app-data/security/security.log
INTERNAL_TOKEN=<RANDOM_INTERNAL_TOKEN>
# --- Плагины и модули ---
PLUGIN_PRESET=pult,prometheus,postgres,csv,json,gitlab,elasticsearch,clickhouse
MODULE_PRESET=rsm
# --- Кеширование ---
FEATURE_DASHBOARD_CACHE=true
INTERNAL_WARMUP_URL=http://backend:5000/internal/cache/warmup-dashboard
CACHE_WORKER_INTERVAL_SEC=30
CACHE_HARD_MAX_STALE_SEC=900
TARANTOOL_CACHE_HOST=tarantool-cache
TARANTOOL_CACHE_PORT=3301
# --- Оповещения (нужны, только если используется модуль оповещений) ---
FEATURE_ALERTING=true
ALERTING_WORKER_INTERVAL_SEC=30
ALERTING_WORKER_LOCALE=ru-RU
NOTIFICATION_SERVICE_URL=http://notification-service:8080
NOTIFICATION_SERVICE_TOKEN=<NOTIFICATION_SERVICE_TOKEN>
NOTIFICATION_SERVICE_TIMEOUT_MS=10000
# --- RSM модуль ---
RSM_MODULE_VERSION=1.3.1
RSM_MODULE_API_BASE_URL=http://rsm-module-api:8080
RSM_MODULE_FRONTEND_HOST=http://<HOST_IP>:8202
RSM_MODULE_BUILD_TIMESTAMP=
Пароль в .env_mongo указывается в исходном виде. В MONGO_URI пароль является частью
URI, поэтому специальные символы в нём должны быть URL-кодированы. Например, если пароль
в .env_mongo равен Example@2026, в .env_backend используйте Example%402026:
MONGO_URI=mongodb://admin:Example%402026@mongo:27017/grafinya?authSource=admin&replicaSet=rs0
Это важно для @, :, /, ?, #, [, ] и %. Конструктор развёртывания кодирует
пароль в MONGO_URI автоматически; вручную кодировать пароль в .env_mongo не нужно.
Начиная с версии 2026H1.1 MongoDB запускается как реплика-сет из одного узла с именем rs0. В docker-compose.yml это три изменения, которые конструктор вносит сам:
- контейнер
mongoстартует командойmongod --replSet rs0 --bind_ip_all --keyFile /run/secrets/mongo-replica-keyи получает ключ через секциюsecretsиз переменнойMONGO_REPLICA_SET_KEY; - у контейнера
mongoпоявился healthcheck: он проверяет доступность базы под учётной записью из.env_mongo; - добавлен разовый сервис
mongo-rs-initиз того же образа, что иmongo. Он инициализирует реплика-сет после того, какmongoпройдёт healthcheck, и завершается. Остальные сервисы ждут его успешного завершения и только потом стартуют сами.
Реплика-сет настраивается независимо от того, используется ли модуль оповещений: это часть базовой конфигурации MongoDB в поставке. Параметр replicaSet=rs0 должен присутствовать во всех строках подключения — и в .env_backend, и в .env_notification. Убирать его или возвращать MongoDB в одиночный режим не нужно и не поддерживается.
Транзакции, ради которых реплика-сет и понадобился, использует только воркер оповещений: состояние правила, история и очередь уведомлений записываются одной транзакцией. При выключенном модуле реплика-сет просто не задействуется.
В 2026H1.1.1 образ database-app переходит с MongoDB 6.0 на MongoDB 8.0. Данные переносятся автоматически при первом старте нового образа: контейнер mongo сам выполняет шаги featureCompatibilityVersion 6.0 → 7.0 → 8.0 и только затем запускает базу. Ничего выполнять вручную не нужно, в журнале контейнера появятся строки pult-mongo-upgrade:.
- Перед обновлением сделайте резервную копию тома
mongo-data. Вернуться на образ с MongoDB 6.0 после миграции нельзя — это ограничение MongoDB. - Миграция занимает секунды и укладывается в healthcheck контейнера
mongo. Если контейнер не стартует, причина будет в его журнале:docker compose logs mongo. - В образе остались только утилиты
mongodumpиmongorestore;mongoexport,mongoimportи остальные удалены.
Начиная с плагинов 1.3.5 ключ, которым плагины шифруют пароли источников данных, можно задать переменной окружения SDK_ENCRYPT_SECRET у сервисов плагинов. Если переменная не задана, используется прежний ключ, и ничего делать не нужно. Задавать её стоит до первого запуска плагинов 1.3.5 и затем не менять: пароли, сохранённые с одним ключом, не расшифровываются другим.
Переносить или выгружать базу не нужно: данные остаются в томе mongo-data, реплика-сет инициализируется поверх них. Достаточно привести конфигурацию к виду, описанному на этой странице.
-
Создайте рядом с
docker-compose.ymlфайл.envс ключомMONGO_REPLICA_SET_KEY— как описано в Шаге 1. Раньше этого файла в установке не было. -
Приведите
docker-compose.ymlк примеру из Шага 1: у сервисаmongo—command,secretsиhealthcheck; новый сервисmongo-rs-init; секцияsecretsв конце файла; уbackend,cache-workerи остальных сервисов —depends_on: mongo-rs-init: condition: service_completed_successfullyвместо прежнего списка- mongo. -
Допишите
&replicaSet=rs0вMONGO_URI— в.env_backendи, если используется модуль оповещений, в.env_notification. -
Обновите теги образов на актуальные из этой страницы:
2026H1.1.1для компонентов портала,1.3.5для плагинов иrsm-module-api. -
Из каталога с
.envвыполните:docker compose pulldocker compose up -d -
Убедитесь, что реплика-сет поднялся:
docker compose logs mongo-rs-initdocker compose psКонтейнер
mongo-rs-initдолжен завершиться в состоянииExited (0).
Порядок шагов важен: не добавляйте replicaSet=rs0 в MONGO_URI, пока контейнер mongo не запущен с --replSet rs0. Иначе backend не найдёт primary и не стартует. Обратный переход в одиночный режим не поддерживается.
Обязательно замените:
DB_LOGINиDB_PASSWORDна реальные учётные данные MongoDBJWT_SECRET,JWT_REFRESH_SECRETиINTERNAL_TOKENна собственные безопасные значенияNOTIFICATION_SERVICE_TOKENна собственное значение — то же самое надо указать в переменнойSERVICE_TOKENсервиса уведомленийALLOWED_ORIGINна фактический адрес frontendRSM_MODULE_FRONTEND_HOSTна внешний адресrsm-module-ui
Параметр SECURITY_LOG_FILE_PATH остаётся в .env_backend, а в docker-compose.yml дополнительно прокидывается в контейнер backend с fallback-значением /app-data/security/security.log. Для сохранения журнала между перезапусками используется volume security-log-data.
Если кеширование или модуль РСМ не нужны, конструктор автоматически уберёт соответствующие сервисы и связанные переменные.
ALLOWED_ORIGIN — адрес, по которому пользователи открывают портал в браузере: со схемой и, если порт нестандартный, с портом, без слэша на конце. Например http://192.168.0.1, http://192.168.0.1:8080, https://grafinya.example.ru. Значение используется и как адрес возврата после входа через SAML, поэтому при неверном значении вход по SAML завершится ошибкой.
AUTH_COOKIE_MODE — режим выдачи браузерной сессии. Значение по умолчанию dual; переменную можно не указывать. Явно задают только при необходимости:
| Значение | Поведение |
|---|---|
dual | Значение по умолчанию. Подходит для обычной установки |
only | Целевой режим: браузерная сессия выдаётся только в cookie |
off | Режим совместимости для отката, если после обновления вход в портал не работает |
Авторизация интеграций по API-токену работает одинаково во всех режимах.
d. .env_frontend:VITE_API_BASE_URL=http://<HOST>:5000/api/v1
API_PROXY_TARGET=http://backend:5000
VITE_FEATURE_DASHBOARD_CACHE=true
VITE_FEATURE_DASHBOARD_FORECAST=true
VITE_FEATURE_ALERTING=true
NGINX_HOST=<HOST>
NGINX_PORT=80
Обязательно замените VITE_API_BASE_URL на адрес backend API, доступный из браузера пользователя. Пример:
VITE_API_BASE_URL=http://192.168.0.1:5000/api/v1
API_PROXY_TARGET=http://backend:5000
VITE_FEATURE_DASHBOARD_CACHE=true
VITE_FEATURE_DASHBOARD_FORECAST=true
VITE_FEATURE_ALERTING=true
NGINX_HOST=192.168.0.1
NGINX_PORT=80
Параметры NGINX_HOST и NGINX_PORT необязательны и используются только при необходимости явно настроить host и port для Nginx-контейнера.
Параметры VITE_FEATURE_DASHBOARD_CACHE, VITE_FEATURE_DASHBOARD_FORECAST и VITE_FEATURE_ALERTING должны быть заданы явно как true или false; пустое значение приведёт к некорректной генерации runtime-конфига frontend.
API_PROXY_TARGET — адрес backend, по которому к нему обращается контейнер frontend. Браузер работает с API через тот же адрес, что и с порталом: nginx контейнера frontend проксирует путь /api/.
- Указывайте имя сервиса backend из
docker-compose.ymlи порт, без пути и без слэша на конце:http://backend:5000. - Переменная необязательная. Если её не задать, адрес выводится из
VITE_API_BASE_URL— тогда контейнер frontend обращается к опубликованному порту хоста и возвращается обратно в сеть Docker, что зависит от настроек межсетевого экрана. Явное имя сервиса делает обращение прямым. VITE_API_BASE_URLостаётся обязательным и по-прежнему указывает адрес backend, доступный из браузера: он нужен интеграциям и странице настроек аутентификации.
Шаг 2: Модуль оповещений
Шаг нужен, только если планируется использовать оповещения. Ядро Графини работает и без модуля: при FEATURE_ALERTING=false backend не поднимает API оповещений, воркер завершает работу, раздел в интерфейсе скрыт.
Переменные и сервисы, которые нужны только этому модулю:
| Что | Где |
|---|---|
FEATURE_ALERTING | .env_backend |
ALERTING_WORKER_INTERVAL_SEC, ALERTING_WORKER_LOCALE | .env_backend |
NOTIFICATION_SERVICE_URL, NOTIFICATION_SERVICE_TOKEN, NOTIFICATION_SERVICE_TIMEOUT_MS | .env_backend |
VITE_FEATURE_ALERTING | .env_frontend |
Весь файл .env_notification | сервис уведомлений |
Сервис alerting-worker | docker-compose.yml Графини |
Сервис notification-service | docker-compose.yml Графини |
Всё остальное из «Шага 1» — включая реплика-сет MongoDB, AUTH_COOKIE_MODE и API_PROXY_TARGET — от модуля не зависит и настраивается одинаково в любой установке.
Включение модуля
Задайте FEATURE_ALERTING=true в .env_backend и VITE_FEATURE_ALERTING=true в .env_frontend. Без первого недоступен API оповещений и не работает воркер оценки правил, без второго раздел скрыт в интерфейсе.
Правила оценивает отдельный сервис alerting-worker — конструктор добавляет его в docker-compose.yml вместе с остальными сервисами Графини.
Переменная .env_backend | Назначение |
|---|---|
ALERTING_WORKER_INTERVAL_SEC | Период цикла воркера в секундах. Значение по умолчанию — 30 |
ALERTING_WORKER_LOCALE | Язык служебных сообщений воркера: ru-RU или en-GB |
Остальные параметры — срок хранения событий, интервал оценки правил и тайминги группировки — задаются в интерфейсе, в разделе «Администрирование → Оповещения».
Сервис уведомлений
Сообщения (электронная почта, webhook, Telegram) отправляет отдельный сервис notification-service. Конструктор добавляет его в тот же docker-compose.yml, что и остальные сервисы Графини: та же сеть Docker, свой файл переменных .env_notification и ожидание mongo-rs-init, как у backend и воркеров.
Порт сервиса наружу не публикуется. К нему обращается только backend по внутреннему адресу http://notification-service:8080, а сообщения сервис отправляет сам — входящие соединения снаружи ему не нужны. Служебные адреса /health и /metrics отдаются без авторизации, поэтому публиковать порт на хосте не следует.
Связь настраивается тремя переменными .env_backend:
| Переменная | Назначение |
|---|---|
NOTIFICATION_SERVICE_URL | Адрес сервиса в сети Docker. По умолчанию http://notification-service:8080 |
NOTIFICATION_SERVICE_TOKEN | Общий служебный токен. Значение должно совпадать с SERVICE_TOKEN сервиса уведомлений |
NOTIFICATION_SERVICE_TIMEOUT_MS | Таймаут обращения к сервису в миллисекундах. По умолчанию 10000 |
Со стороны сервиса уведомлений переменные задаются в файле .env_notification:
MONGO_INITDB_ROOT_USERNAME=<DB_LOGIN>
MONGO_INITDB_ROOT_PASSWORD=<DB_PASSWORD>
MONGO_INITDB_DATABASE=grafinya
MONGO_URI=mongodb://<DB_LOGIN>:<DB_PASSWORD>@mongo:27017/grafinya?authSource=admin&replicaSet=rs0
SERVICE_TOKEN=<NOTIFICATION_SERVICE_TOKEN>
SECRETS_ENCRYPTION_KEY=<64_HEX_CHARS>
PORTAL_URL=http://<HOST>
CONFIG_CACHE_TTL=0
| Переменная | Назначение |
|---|---|
MONGO_URI | Та же база, что у Графини, обязательно с replicaSet=rs0 |
SERVICE_TOKEN | Обязательная. То же значение, что в NOTIFICATION_SERVICE_TOKEN |
SECRETS_ENCRYPTION_KEY | Ключ шифрования секретов уведомлений (пароль SMTP, токен бота, заголовки webhook). 64 шестнадцатеричных символа |
PORTAL_URL | Адрес портала, по которому его открывает получатель письма. Подставляется в ссылки в тексте уведомления. Если не задать, ссылки будут пустыми |
CONFIG_CACHE_TTL | Время кеширования настроек. Оставьте 0 |
PORT | Порт сервиса, по умолчанию 8080 |
Дополнительные параметры отправки — MAX_RETRIES, BACKOFF_BASE, BACKOFF_MAX, WEBHOOK_TIMEOUT, RATE_LIMIT_REQUESTS, RATE_LIMIT_PERIOD — имеют разумные значения по умолчанию и меняются только при необходимости.
Без SECRETS_ENCRYPTION_KEY уведомления не сохраняются: при попытке сохранить портал ответит ошибкой. Секреты — пароль SMTP, токен бота, заголовки авторизации webhook — шифрует сервис уведомлений, и без ключа он отклоняет запрос. Ключ обязателен для любой установки с модулем оповещений.
Задайте ключ до создания первого уведомления: смена ключа на заполненной базе не поддерживается — уже сохранённые секреты станут нечитаемыми, и их придётся ввести заново во всех уведомлениях организации.
Сгенерировать значение можно так:
openssl rand -hex 32
Шаг 3: Плагины
Текущий конструктор установки поддерживает следующие плагины:
prometheus-pluginна порту8080pult-pluginна порту8081csv-pluginна порту8082postgres-pluginна порту8083json-pluginна порту8084gitlab-pluginна порту8085elasticsearch-pluginна порту8086clickhouse-pluginна порту8087
В примере выше эти плагины уже добавлены в docker-compose.yml. Если нужен не полный набор, конструктор автоматически уберёт лишние сервисы и скорректирует переменную PLUGIN_PRESET в .env_backend.
Шаг 4: Аутентификация в Docker Registry
Для установки Графини, модуля оповещений и модуля РСМ выполните вход в приватные Docker-реестры:
docker login registry.pult.chislitellab.ru:8124
docker login registry.pult.chislitellab.ru:8126
Введите свои учётные данные при запросе.
Шаг 5: Запуск сервисов
Запустите сервисы с помощью Docker Compose:
docker compose up -d
Шаг 6: Проверка работы сервисов
После запуска проверьте, что контейнеры работают:
docker compose ps
Для конфигурации по умолчанию должны быть активны следующие сервисы:
mongomongo-rs-init— разовая инициализация реплика-сета, после успешного выполнения останавливаетсяtarantool-cachebackendcache-workerfrontendprometheus-pluginpult-plugincsv-pluginpostgres-pluginjson-plugingitlab-pluginelasticsearch-pluginclickhouse-pluginrsm-module-apirsm-module-ui
При включённом модуле оповещений к ним добавляются alerting-worker и notification-service.
Проверьте, что реплика-сет инициализирован:
docker compose logs mongo-rs-init
В выводе должно быть сообщение об успешной инициализации rs0, а сам контейнер — в состоянии Exited (0).
Проверьте, что frontend отдаёт относительный адрес API:
curl -s http://<HOST>/env.js
В ответе должно быть API_BASE_URL: '/api/v1', а не абсолютный адрес.
Проверьте, что запросы к API проходят через frontend:
curl -si http://<HOST>/api/v1/auth/authorization-type
Первая строка ответа должна быть HTTP/1.1 200 OK.
Важные замечания
- Для production-окружения обязательно используйте собственные значения
JWT_SECRET,JWT_REFRESH_SECRETиINTERNAL_TOKEN. - Для ограничения доступа к API укажите корректный
ALLOWED_ORIGIN. - Если вы не используете кеширование, отключите его через конструктор или вручную уберите
tarantool-cache,cache-workerи связанные переменныеFEATURE_DASHBOARD_CACHE,INTERNAL_WARMUP_URL,CACHE_WORKER_INTERVAL_SEC,CACHE_HARD_MAX_STALE_SEC,TARANTOOL_CACHE_HOST,TARANTOOL_CACHE_PORT. - Если вы не используете модуль РСМ, отключите его через конструктор или вручную удалите
rsm-module-api,rsm-module-uiи переменныеMODULE_PRESET,RSM_MODULE_*. - Если вы не используете оповещения, задайте
FEATURE_ALERTING=falseиVITE_FEATURE_ALERTING=false, уберите сервисыalerting-workerиnotification-service, файл.env_notificationи переменныеALERTING_WORKER_*иNOTIFICATION_SERVICE_*. Реплика-сетrs0, сервисmongo-rs-init,MONGO_REPLICA_SET_KEYи параметрreplicaSet=rs0вMONGO_URIпри этом остаются — они часть базовой конфигурации MongoDB. - Версии образов backend, frontend и воркеров должны совпадать между собой.
- Порт
5000у backend остаётся опубликованным — он нужен интеграциям, которые обращаются к API по токену.
Диагностика
Запросы к API отвечают 502. Контейнер frontend не достучался до backend по адресу прокси. Проверьте API_PROXY_TARGET, имя сервиса backend в docker-compose.yml и что оба контейнера в одной сети Docker.
Страницы модуля РСМ не открываются, в консоли браузера ERR_CONNECTION_TIMED_OUT на /module/rsm/module.js. Браузер не достучался до rsm-module-ui. Бандл модуля грузится по абсолютному адресу из RSM_MODULE_FRONTEND_HOST, в обход nginx фронтенда, поэтому этот адрес и порт должны быть доступны именно с рабочего места пользователя. Проверьте по шагам:
# 1. Контейнер поднят и порт слушается — выполнять на хосте с docker
docker compose ps rsm-module-ui
ss -lntp | grep 8202
# 2. Адрес доступен с машины пользователя — выполнять там, где открыт браузер
curl -v --max-time 5 http://<HOST_IP>:8202/module/rsm/module.js
# 3. Портал отдаёт браузеру именно этот адрес
docker compose exec mongo mongosh -u <DB_LOGIN> -p <DB_PASSWORD> --authenticationDatabase admin grafinya \
--eval "db.modules.findOne({name:'rsm'},{frontendHost:1,baseUrl:1})"
Если контейнер работает, но curl с рабочего места отваливается по таймауту — закрыт порт в firewall. Если в базе адрес отличается от RSM_MODULE_FRONTEND_HOST (например, внутренний http://rsm-module-ui:3000/), исправьте его на странице модуля в разделе «Модули» портала.
В интерфейсе не работает вход после обновления. Временное решение — задать AUTH_COOKIE_MODE=off в .env_backend и перезапустить backend.
Уведомления не отправляются, в журнале доставки пусто. Проверьте, что сервис уведомлений запущен и виден по адресу из NOTIFICATION_SERVICE_URL, что NOTIFICATION_SERVICE_TOKEN и SERVICE_TOKEN совпадают и что в обеих строках MONGO_URI есть replicaSet=rs0.
Контейнер mongo-rs-init завершается с ошибкой. Реплика-сет не инициализирован, транзакции недоступны. Проверьте учётные данные в .env_mongo и что контейнер mongo запущен с ключом --replSet rs0.