Перейти к основному содержимому
Версия: Графиня 2026H1.1

Установка

Система "Графиня" разворачивается в Docker-контейнерах при помощи Docker Compose. В качестве СУБД используется MongoDB. Для скачивания docker-образов компонентов Графини необходимо воспользоваться учётной записью в репозитории Лаборатории Числитель.

После установки веб-интерфейс будет доступен по адресу http://<HOST> или http://<HOST>:<PORT>, в зависимости от настроенного порта frontend.

Данные для авторизации в веб-интерфейсе "Графини" по умолчанию: Логин: admin / Пароль: 123456

На первом входе система запросит смену пароля.

Предварительные требования​

  1. Установленные Docker и Docker Compose.
  2. Доступ к приватному реестру образов registry.pult.chislitellab.ru:8124.
  3. Если используются модуль оповещений или модуль РСМ, также нужен доступ к реестру registry.pult.chislitellab.ru:8126.
  4. Пользователь с правами на скачивание образов из указанных реестров.

Шаг 1: Подготовка окружения​

Для быстрой подготовки файлов можно воспользоваться Конструктором развёртывания Графини. Он генерирует:

  • docker-compose.yml
  • .env
  • .env_mongo
  • .env_backend
  • .env_frontend
  • .env_notification
  • README.md с краткой сводкой по выбранной конфигурации

Ниже приведён расширенный пример для версии 2026H1.1.1 "Салон": кеширование включено, модуль оповещений и модуль РСМ включены, а в docker-compose.yml добавлены все плагины, поддерживаемые текущим конструктором установки.

  1. Создайте рабочую директорию для проекта:
mkdir grafinya && cd grafinya
  1. Создайте файл 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
warning

Параметр 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-сети.

warning

В образах 2026H1.1 переменная RSM_MODULE_FRONTEND_HOST применяется только при создании записи модуля в базе. При обновлении поверх существующей базы значение из .env_backend игнорируется, и модуль остаётся с прежним адресом. Проверьте адрес модуля в разделе «Модули» портала и при необходимости исправьте его вручную. В последующих релизах значение применяется при каждом старте backend и перекрывает правки в интерфейсе.

В примере выше сервисы alerting-worker и notification-service относятся к модулю оповещений. Если модуль не нужен, оба сервиса можно не описывать — остальная конфигурация от этого не меняется. Сервисы mongo и mongo-rs-init нужны всегда.

  1. Создайте необходимые .env-файлы.
a. .env_mongo:
MONGO_INITDB_ROOT_USERNAME=<DB_LOGIN>
MONGO_INITDB_ROOT_PASSWORD=<DB_PASSWORD>
MONGO_INITDB_DATABASE=grafinya
warning

Обязательно укажите свои DB_LOGIN и DB_PASSWORD, иначе система не запустится корректно. Пример:

MONGO_INITDB_ROOT_USERNAME=admin
MONGO_INITDB_ROOT_PASSWORD=123456
MONGO_INITDB_DATABASE=grafinya
b. .env:
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 не нужно.

MongoDB работает как реплика-сет

Начиная с версии 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: MongoDB 8.0

В 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, реплика-сет инициализируется поверх них. Достаточно привести конфигурацию к виду, описанному на этой странице.

  1. Создайте рядом с docker-compose.yml файл .env с ключом MONGO_REPLICA_SET_KEY — как описано в Шаге 1. Раньше этого файла в установке не было.

  2. Приведите 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.

  3. Допишите &replicaSet=rs0 в MONGO_URI — в .env_backend и, если используется модуль оповещений, в .env_notification.

  4. Обновите теги образов на актуальные из этой страницы: 2026H1.1.1 для компонентов портала, 1.3.5 для плагинов и rsm-module-api.

  5. Из каталога с .env выполните:

    docker compose pull
    docker compose up -d
  6. Убедитесь, что реплика-сет поднялся:

    docker compose logs mongo-rs-init
    docker compose ps

    Контейнер mongo-rs-init должен завершиться в состоянии Exited (0).

Порядок шагов важен: не добавляйте replicaSet=rs0 в MONGO_URI, пока контейнер mongo не запущен с --replSet rs0. Иначе backend не найдёт primary и не стартует. Обратный переход в одиночный режим не поддерживается.

warning

Обязательно замените:

  • DB_LOGIN и DB_PASSWORD на реальные учётные данные MongoDB
  • JWT_SECRET, JWT_REFRESH_SECRET и INTERNAL_TOKEN на собственные безопасные значения
  • NOTIFICATION_SERVICE_TOKEN на собственное значение — то же самое надо указать в переменной SERVICE_TOKEN сервиса уведомлений
  • ALLOWED_ORIGIN на фактический адрес frontend
  • RSM_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
warning

Обязательно замените 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-workerdocker-compose.yml Графини
Сервис notification-servicedocker-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 — имеют разумные значения по умолчанию и меняются только при необходимости.

warning

Без SECRETS_ENCRYPTION_KEY уведомления не сохраняются: при попытке сохранить портал ответит ошибкой. Секреты — пароль SMTP, токен бота, заголовки авторизации webhook — шифрует сервис уведомлений, и без ключа он отклоняет запрос. Ключ обязателен для любой установки с модулем оповещений.

Задайте ключ до создания первого уведомления: смена ключа на заполненной базе не поддерживается — уже сохранённые секреты станут нечитаемыми, и их придётся ввести заново во всех уведомлениях организации.

Сгенерировать значение можно так:

openssl rand -hex 32

Шаг 3: Плагины​

Текущий конструктор установки поддерживает следующие плагины:

  • prometheus-plugin на порту 8080
  • pult-plugin на порту 8081
  • csv-plugin на порту 8082
  • postgres-plugin на порту 8083
  • json-plugin на порту 8084
  • gitlab-plugin на порту 8085
  • elasticsearch-plugin на порту 8086
  • clickhouse-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

Для конфигурации по умолчанию должны быть активны следующие сервисы:

  • mongo
  • mongo-rs-init — разовая инициализация реплика-сета, после успешного выполнения останавливается
  • tarantool-cache
  • backend
  • cache-worker
  • frontend
  • prometheus-plugin
  • pult-plugin
  • csv-plugin
  • postgres-plugin
  • json-plugin
  • gitlab-plugin
  • elasticsearch-plugin
  • clickhouse-plugin
  • rsm-module-api
  • rsm-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.

Важные замечания​

  1. Для production-окружения обязательно используйте собственные значения JWT_SECRET, JWT_REFRESH_SECRET и INTERNAL_TOKEN.
  2. Для ограничения доступа к API укажите корректный ALLOWED_ORIGIN.
  3. Если вы не используете кеширование, отключите его через конструктор или вручную уберите 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.
  4. Если вы не используете модуль РСМ, отключите его через конструктор или вручную удалите rsm-module-api, rsm-module-ui и переменные MODULE_PRESET, RSM_MODULE_*.
  5. Если вы не используете оповещения, задайте 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.
  6. Версии образов backend, frontend и воркеров должны совпадать между собой.
  7. Порт 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.