Skip to content

Руководство по разработке ​

В среде разработки docker-compose.dev.yml запускает сервисы-зависимости и позволяет независимо запускать backend на Go, веб-фронтенд и docreader. После изменений в коде собирайте и тестируйте соответствующий модуль, а затем проверяйте связанные пути интеграции.

Технологический стек и требования к окружению ​

Платформа состоит из трёх независимо разрабатываемых процессов:

КомпонентКаталогЯзык / среда выполненияТребования к версии (источник)
Основной backend appcmd/server + internal/GoGo 1.26.0 (go 1.26.0 в go.mod), требуется CGO (привязки DuckDB, sqlite-vec)
Сервис разбора документов docreaderdocreader/Python + gRPCPython >= 3.10.18 (requires-python в docreader/pyproject.toml); зависимости управляются через uv (в репозитории есть uv.lock, в Docker — uv sync --locked)
Фронтенд frontendfrontend/Node.js + Vue 3Ветка Node 22 (devDependencies содержит @tsconfig/node22, @types/node ^22), Vite 7 + TypeScript ~6.0 + Vue 3.5 + TDesign, версия 0.8.3
CLIcli/ (отдельный Go-модуль)GoGo 1.26 (матрица go: ['1.26'] в .github/workflows/cli.yml)

Рекомендуемые дополнительные инструменты разработки:

bash
# CLI миграций базы данных (используется scripts/migrate.sh)
go install -tags 'postgres' github.com/golang-migrate/migrate/v4/cmd/migrate@latest

# Проверка кода (вызывается make lint)
# Способ установки см. на https://golangci-lint.run; в корне репозитория есть конфигурация .golangci.yml

# Генерация документации Swagger (вызывается make docs)
make install-swagger    # go install github.com/swaggo/swag/cmd/swag@latest

# Управление зависимостями Python
pip install uv          # docreader устанавливает зависимости через uv sync

# Docker + Docker Compose (подойдёт как плагин v2, так и отдельный docker-compose; scripts/dev.sh определяет автоматически)

Быстрый старт: режим разработки (рекомендуется) ​

В режиме разработки инфраструктура работает в Docker, а app и frontend — локально. После изменения кода приложения процессы можно просто перезапустить, без пересборки образов зависимостей. Точка входа — scripts/dev.sh; цели dev-* в Makefile инкапсулируют соответствующие операции.

bash
# 1. Подготовьте переменные окружения: dev.sh загрузит .env (обязателен), затем перекроет .env.local (опционально)
cp .env.example .env

# 2. Запустите инфраструктуру (ParadeDB/Postgres + Redis + docreader, по умолчанию ещё Langfuse)
make dev-start                      # эквивалент ./scripts/dev.sh start
make dev-start DEV_ARGS=--qdrant    # подключить дополнительный profile

# 3. В другом терминале: локальный запуск backend (внутри выполняет go run -ldflags=... ./cmd/server)
make dev-app                        # эквивалент ./scripts/dev.sh app

# 4. Ещё один терминал: локальный запуск фронтенда (cd frontend && npm install && npm run dev)
make dev-frontend                   # эквивалент ./scripts/dev.sh frontend

# Прочее
make dev-status   # статус контейнеров
make dev-logs     # логи
make dev-stop     # остановка
make dev-restart  # перезапуск

Dev-сервер фронтенда слушает 5173 (server.port: 5173 в frontend/vite.config.ts) и проксирует /api, /files и /mcp/ на backend. Цель прокси берётся последовательно из переменных окружения процесса VITE_DEV_PROXY_TARGET, FRONTEND_BACKEND_URL; если обе не заданы или пусты, используется http://localhost:8080. DEV_PROXY_TARGET — внутренняя константа в конфигурационном файле, а не переменная окружения.

При подключении к удалённому backend можно задать значение в .env.local в корне репозитория (замените примерный адрес фактическим адресом backend):

bash
VITE_DEV_PROXY_TARGET=https://kb.example.com

Затем в корне репозитория выполните make dev-frontend; скрипт сначала загрузит .env из корня, затем переопределит его из .env.local и экспортирует переменные для Vite. После изменения цели прокси dev-сервер фронтенда нужно перезапустить.

Если запускать npm-команды напрямую в каталоге frontend/, переменную окружения нужно передавать явно; такой способ не проходит через загрузку файлов окружения из корна репозитория:

bash
cd frontend
VITE_DEV_PROXY_TARGET=https://kb.example.com npm run dev

vite preview (порт 4173) поднимает сервис на production-сборке и является наиболее близкой к release-образу средой проверки. Он использует те же пути прокси и те же правила выбора цели: после выполнения npm run build в каталоге frontend/ к удалённому backend можно подключиться командой VITE_DEV_PROXY_TARGET=https://kb.example.com npm run preview.

Список сервисов docker-compose.dev.yml ​

docker-compose.dev.yml содержит только сервисы-зависимости, без app/frontend. Ниже перечислены сервисы, запускаемые по умолчанию и опционально через profile (profile включается параметром dev.sh start):

СервисОбразПорт (по умолчанию)Условие запуска
postgresparadedb/paradedb:v0.25.11-pg17 (со встроенным pg_search/BM25)5432по умолчанию
redisredis:7.0-alpine (--requirepass)6379по умолчанию
docreaderлокальная сборка docker/Dockerfile.docreader50051 (gRPC)по умолчанию
searxng (+searxng-init)searxng/searxng:latest127.0.0.1:8888--searxng / --full (compose profile searxng)
miniopgsty/minio:latest9000 / консоль 9001--minio / --full
qdrantqdrant/qdrant:v1.16.26333 / 6334--qdrant / --full
opensearchopensearchproject/opensearch:3.3.2 (security отключён, чистый HTTP)9200profile opensearch / full
opensearch-dashboardsopensearchproject/opensearch-dashboards:3.3.05601profile opensearch-ui (запускается отдельно по необходимости)
milvusmilvusdb/milvus:v2.6.11 (standalone, встроенный etcd)19530 / 9091profile milvus / full
neo4jneo4j:latest (плагин APOC)7474 / 7687--neo4j / --full
dexdexidp/dex:latest (тестовый источник идентификации OIDC, конфигурация misc/dex-config.yaml)5556--dex / --full
langfuse-web / langfuse-worker / langfuse-clickhouse / langfuse-minio / langfuse-db-initСамостоятельно размещаемый стек Langfuse v3, использует dev-postgres (отдельная БД langfuse) и redis (DB 1)web 3000, minio 9100/9101--langfuse (в dev.sh включён по умолчанию, отключается --no-langfuse)
odl-hybridлокальная сборка docker/Dockerfile.odl-hybrid (PDF-бэкенд Docling)5002--odl-hybrid (образ большой, по необходимости)
sandboxwechatopenai/weknora-sandbox (песочница выполнения скриптов Skills, только build/pull, не постоянно)-profile full

Опциональные параметры dev.sh start: --minio, --qdrant, --neo4j, --dex, --langfuse (включён по умолчанию), --no-langfuse, --odl-hybrid, --full (все опциональные сервисы, кроме odl-hybrid). Передача параметров через Makefile: make dev-start DEV_ARGS=--odl-hybrid.

Локальный запуск docreader отдельно ​

dev-start по умолчанию запускает docreader в контейнере; если нужно отлаживать Python-код локально:

bash
cd docreader
uv sync                       # установка зависимостей по uv.lock (в контейнере — uv sync --locked --no-dev)
uv run -m docreader.main      # запуск gRPC-сервиса (совпадает с CMD в Dockerfile), слушает DOCREADER_GRPC_PORT (по умолчанию 50051)

Многочисленные параметры тонкой настройки docreader (DPI рендеринга PDF, определение сканов, белый список SSRF, gRPC TLS и т. д.) задаются переменными окружения DOCREADER_*; полный список см. в разделе docreader.environment файла docker-compose.dev.yml.

Режим Lite (без внешних зависимостей) ​

Режим Lite компилирует SQLite (+sqlite-vec) и очередь в памяти в один бинарник; подходит для быстрого знакомства и десктопной версии:

bash
make build-lite     # сначала собрать фронтенд в web/, затем CGO-сборка Go (tags: sqlite_fts5); SKIP_FRONTEND=1 пропускает фронтенд
make run-lite       # требует .env.lite, собирает и запускает Lite-версию
make package-lite   # собрать tarball-дистрибутив (scripts/package-lite.sh)
make package-mac-app  # собрать macOS .app (scripts/package-mac-app.sh)

Обзор целей Makefile ​

Перечисленные цели определены в корневом Makefile; make help также выводит справку.

Базовая сборка и запуск ​

ЦельНазначение
buildgo build -o WeKnora ./cmd/server
runсначала build, затем запуск ./WeKnora
testgo test -v ./...
cleango clean и удаление бинарника
build-prodProduction-сборка: CGO_ENABLED=1, -ldflags "-w -s" внедряет Version/CommitID/BuildTime/GoVersion (переменные пакета internal/handler) и задаёт protobuf conflictPolicy=warn (во избежание конфликтов proto qdrant/milvus)
fmtgo fmt ./...
lintgolangci-lint run
depsgo mod download
docsгенерирует документацию Swagger командой swag init (параметры см. в Makefile, включая --overridesFile ./docs/swag.overrides)
install-swaggerустанавливает CLI swag

Управление Docker-образами и сервисами ​

ЦельНазначение
docker-build-appсобирает wechatopenai/weknora-app (docker/Dockerfile.app, внедряет информацию о версии из scripts/get_version.sh)
docker-build-docreaderсобирает wechatopenai/weknora-docreader (docker/Dockerfile.docreader)
docker-build-frontendмногоэтапная сборка wechatopenai/weknora-ui (в builder npm ci + npm run build, предварительная сборка dist на хосте не нужна; автоматически внедряет VITE_FRONTEND_COMMIT из git)
docker-build-allвсе три образа выше
docker-runгарантирует наличие .env (при отсутствии копирует из .env.example или создаёт пустой) и выполняет docker-compose up
docker-stop / docker-restartdocker-compose down / stop -t 60 + up
start-all / stop-allscripts/start_all.sh (запуск/остановка всех сервисов одной командой)
start-ollama / start-dockerstart_all.sh --ollama / --docker
build-images / build-images-app / build-images-docreader / build-images-frontend / clean-imagesscripts/build_images.sh собирает/очищает образы из исходников
check-env / list-containers / pull-imagesstart_all.sh --check / --list / --pull
show-platformпоказывает uname -m и платформу сборки Docker (автоопределение amd64/arm64)
clean-dbудаляет три Docker volume weknora_postgres-data / weknora_minio_data / weknora_redis_data (очищает данные)

Миграции базы данных (подробнее — в главе «База данных и миграции») ​

ЦельНазначение
migrate-up / migrate-downscripts/migrate.sh up / down
migrate-versionпросмотр текущей версии миграций
migrate-create name=xxxсоздаёт пару новых файлов миграции
migrate-force version=Nпринудительно задаёт версию (восстановление из dirty state)
migrate-goto version=Nмиграция к указанной версии

Режим разработки и Lite ​

ЦельНазначение
dev-start / dev-stop / dev-restart / dev-logs / dev-statusscripts/dev.sh start/stop/restart/logs/status (поддерживает передачу параметров profile через DEV_ARGS)
dev-appлокальный go run ./cmd/server (с версионными ldflags)
dev-frontendлокальный npm run dev
build-lite / run-lite / package-lite / package-mac-appсборка/запуск/упаковка режима Lite (см. 2.3)
download_spatialgo run cmd/download/duckdb/duckdb.go скачивает расширение DuckDB spatial (для инструмента анализа данных)

Каталог производителей моделей ​

ЦельНазначение
model-catalog-generatepython3 scripts/model-catalog/generate.py — повторно генерирует метаданные каталога производителей и переопределения протоколов
model-catalog-checkпроверяет актуальность сгенерированных данных и запускает go test ./internal/models/... (CI проверяет так же)
model-catalog-diffсравнивает с models.dev и выводит отчёт о различиях метаданных моделей; только для ручного просмотра, файлы не изменяются; параметр VENDOR=deepseek ограничивает одним производителем

Способ подключения производителей см. в разделе Точки расширения.

Система тестирования ​

Юнит-тесты Go (основной модуль) ​

bash
make test          # go test -v ./...
# или по пакетам:
go test ./internal/infrastructure/chunker/...
go test -run TestXxx ./internal/application/service/...

Тесты основного модуля широко используют in-memory-заглушки go-sqlmock, miniredis и т. п. (см. go.mod); большинство запускается без реальной базы данных. Часть пакетов зависит от CGO (DuckDB/sqlite-vec).

Тесты docreader (Python) ​

Тесты находятся в docreader/tests/, написаны на стандартной библиотеке unittest (в файлах — unittest.main()), покрывают маршрутизацию разбора, параллелизм, разбор EPUB/Excel/MHTML/PDF, защиту от SSRF и т. д.:

bash
cd docreader
uv sync
uv run python -m unittest discover -s tests -v      # все
uv run python -m unittest tests.test_parser_routing  # отдельный

Тесты CLI и приёмочные тесты ​

cli/ — отдельный Go-модуль со своим cli/Makefile:

bash
cd cli
make test            # go test ./...
make test-coverage   # с покрытием
make lint            # go vet

Сквозные контрактные/интеграционные тесты собраны в cli/acceptance/ (см. cli/acceptance/doc.go):

  • cli/acceptance/contract/ — golden-тесты формы вывода envelope JSON + согласованность реестра error.code;
  • cli/acceptance/e2e/ — чёрноящичные тесты (в стиле testscript) против реального сервера aihelpme.ru; требуют переменных окружения, указывающих на тестовый сервер; на стороне CI выполняется через .github/workflows/cli-e2e.yml, запускается по необходимости (workflow_dispatch вручную или метка acceptance-e2e на PR), использует secrets WEKNORA_E2E_HOST / WEKNORA_E2E_TOKEN.

Каталог tests/ и тесты фронтенда ​

  • tests/miniprogram/miniprogram.test.js — интеграционные тесты клиента мини-программы (тестовый скрипт на Node), сейчас единственное содержимое tests/;
  • Фронтенд: cd frontend && npm run type-check (vue-tsc) и npm test (tsx --test, Node test runner).

Стандарты кода и процесс внесения изменений ​

Стандарты кода Go ​

Корневой .golangci.yml (формат конфигурации golangci-lint v2):

yaml
version: 2
linters-settings:
  lll:
    line-length: 120
    tab-width: 4
linters:
  enable:
    - lll           # контролирует ширину строки (120 столбцов)
    - govet
    - revive
formatters:
  enable:
    - gofmt
    - gofumpt

Перед коммитом рекомендуется выполнить:

bash
make fmt && make lint && make test

Обратите внимание: стандарт форматирования — gofumpt (строже, чем gofmt), предельная ширина строки 120.

Можно также установить встроенные Git hooks (./scripts/install-git-hooks.sh, устанавливает core.hooksPath на scripts/git-hooks): pre-commit проверяет пробельные символы, автоматически запускает gofmt и, если установлен, golangci-lint; pre-push, как и CI, выполняет gofmt и go vet / go test / go build. Для временного пропуска задайте SKIP_HOOKS=1; чтобы пропустить только тесты в pre-push — HOOK_SKIP_TEST=1.

При добавлении или обновлении сторонних зависимостей, а также при изменении файлов данных, распространяемых с релизом, необходимо синхронно обновлять THIRD_PARTY_NOTICES.md и licenses/ и проводить самопроверку через scripts/check-license-bundle.sh (app.yml выполняет такие же проверки).

CI и процесс внесения изменений ​

Фактическая конфигурация в .github/:

ФайлПуть-триггерНазначение
workflows/app.ymlGo-код корневого модуля, go.mod, config/, migrations/, scripts/, docker/Dockerfile.app, файлы лицензий, данные каталога моделейПроверки основного модуля: контроль форматирования gofmt (только для коммитов в PR), go vet, go test, go build ./cmd/server; дополнительно проверяет пакет лицензий третьих сторон, результат генерации каталога производителей моделей и тесты Git hooks
workflows/go-lint.yml / go-lint-cache.ymlPR / maingolangci-lint сообщает только о новых проблемах PR относительно базовой линии слияния; go-lint-cache.yml прогревает кэш на main
workflows/frontend.ymlfrontend/, scripts/build_frontend_dist.shNode 24: npm test + npm run type-check + npm run build; дополнительно собирает многоэтапный образ frontend/Dockerfile (без push) и проверяет страницу встраивания и маршрут MCP-прокси внутри образа (scripts/test_embed_nginx.py)
workflows/docreader.ymldocreader/, testdata/, packages/, соответствующие Dockerfileuv устанавливает зависимости → compileall → unittest discover docreader/tests; затем поднимает gRPC-сервис docreader и запускает go test ./docreader/client ./docreader/proto
workflows/mcp-server.ymlmcp-server/Матричные тесты Python 3.10–3.13; после слияния в main автоматически публикует в PyPI через Trusted Publishing по номеру версии из pyproject.toml (если версия уже существует, загрузка пропускается; тег не обязателен)
workflows/cli.ymlcli/Матрица трёх платформ ubuntu/macos/windows, Go 1.26, go build + go test -race -coverprofile + go vet + проверка словаря skill wire
workflows/cli-e2e.ymlвручную / labelСквозная приёмка CLI (метка acceptance-e2e или ручной запуск, см. 4.3)
workflows/docker-image.yml—Сборка и публикация Docker-образов
workflows/release-lite.yml—Публикация версии Lite
workflows/anydoc.ymlthird_party/anydoc-go/, internal/infrastructure/docparser/Сборка и тест внутрипроцессного движка разбора Office
workflows/dsh-plugin.ymlpackages/dsh-weknora/Тест и публикация плагина DeepSeek Harness
pull_request_template.md—Шаблон PR
ISSUE_TEMPLATE/—Шаблоны Issue
dependabot.yml—Бот обновления зависимостей

Четыре проверки, запускаемые по путям (app / frontend / docreader / mcp-server), покрывают основные модули, но локальный прогон всё равно экономит время. Для фронтенда можно сразу использовать scripts/verify_frontend_pr.sh; он выполняет npm test → npm run type-check → npm run build в том же порядке, что и CI.

Процесс внесения изменений: fork / ветка → локально fmt + lint + test → PR (заполняется по шаблону) → запуск CI по затронутым путям.

Приёмы отладки ​

Уровни логирования ​

Логирование реализовано в internal/logger/logger.go (logrus). Уровень управляется переменной окружения LOG_LEVEL, допустимые значения debug / info / warn (warning) / error / fatal; при отсутствии или недопустимом значении по умолчанию используется debug (getLogLevelFromEnv()). LOG_PATH задаёт путь вывода; оба параметра вступают в силу сразу после загрузки .env в main(). На стороне docreader LOG_LEVEL читается так же (пробрасывается в compose).

Каждый запрос несёт X-Request-ID, пронизывающий логи app и docreader (init_logging_request_id в docreader); при диагностике сначала берите request id.

GIN_MODE и Swagger ​

  • При GIN_MODE=release отключается Swagger UI (internal/router/router.go) и меняется безопасное поведение embed channel. При локальной разработке из исходников можно задать debug; если в Docker Compose переменная не задана, по умолчанию используется release.
  • Swagger предоставляется backend app. Адрес по умолчанию — http://localhost:8080/swagger/index.html; если в Compose изменён APP_PORT, используйте соответствующий порт, опубликованный на хосте. Для порта фронтенда (по умолчанию 80) и порта dev-сервера Vite (по умолчанию 5173) прокси /swagger/ не настроен.
  • Релизный образ уже содержит документацию Swagger; make docs нужен только при изменении комментариев интерфейсов, когда требуется перегенерировать документацию и собрать backend.

Шаги доступа в Docker Compose ​

Задайте GIN_MODE=debug в .env проекта, затем пересоздайте контейнер app, чтобы переменная окружения вступила в силу (простой docker compose restart app не обновляет окружение контейнера):

bash
docker compose up -d --no-deps --force-recreate app
docker compose exec app printenv GIN_MODE
docker compose port app 8080

Убедитесь, что первая проверка вывела debug, затем обратитесь к backend по отображённому второй проверкой порту. Например, при выводе 0.0.0.0:8080 с этой же машины откройте http://localhost:8080/swagger/index.html; с другой машины замените localhost на адрес машины развёртывания. После завершения диагностики верните GIN_MODE в release и пересоздайте контейнер app.

Пустая страница или ошибка загрузки после открытия ​

Сначала проверьте, доходит ли запрос до backend (ниже пример с портом backend по умолчанию 8080):

bash
curl -i http://localhost:8080/swagger/index.html
curl -i http://localhost:8080/swagger/doc.json

В норме оба возвращают 200: первый — HTML с swagger-ui, второй — JSON с полями swagger и paths.

СимптомНаправление диагностики
Код состояния 200, но HTML — обычная страница фронтенда (с <div id="app">), страница пустая или перебрасывает на страницу входаЗапрос попал в SPA-фолбэк фронтенда. Используйте порт, отображённый на backend app; фронтенд входа не добавляет для него прокси /swagger/.
Backend возвращает 401 или 404, Swagger UI отсутствуетПроверьте порт доступа и фактический GIN_MODE внутри контейнера; в режиме release маршруты Swagger не регистрируются, и несовпавшие запросы могут попасть в middleware аутентификации.
Swagger UI открывается, но сообщает об ошибке загрузки определения APIОтдельно проверьте ответ /swagger/doc.json того же backend; при использовании собственного обратного прокси убедитесь, что весь путь /swagger/ и статические ресурсы перенаправляются в app.

Отладка базы данных и миграций ​

  • AUTO_MIGRATE=false отключает автоматические миграции при запуске; AUTO_RECOVER_DIRTY (включена по умолчанию, false отключает) управляет автоматическим восстановлением из dirty state (internal/container/container.go). Ошибка миграции только выдаёт предупреждение и не блокирует запуск; обращайте внимание на сообщение Database migration failed в логах запуска.
  • make migrate-version быстро показывает версию schema.

Наблюдаемость цепочки LLM (Langfuse) ​

dev.sh start по умолчанию поднимает самостоятельно размещённый Langfuse (http://localhost:3000). Для локально запущенного через go run app нужно экспортировать:

bash
export LANGFUSE_HOST=http://localhost:3000
export LANGFUSE_PUBLIC_KEY=pk-lf-xxx
export LANGFUSE_SECRET_KEY=sk-lf-xxx

После этого в UI Langfuse можно просматривать trace вызовов моделей для каждой сессии (spans обработки документов также сохраняются в таблицу knowledge_processing_spans и визуализируются во фронтенде).

pprof ​

В текущем коде эндпоинт net/http/pprof не встроен (в internal/, cmd/ нет ссылок на pprof). Для профилирования производительности можно временно добавить в cmd/server/main.go import _ "net/http/pprof" и поднять отдельный http.ListenAndServe("localhost:6060", nil) либо использовать go test -bench . -cpuprofile для профилирования конкретного пакета.

Диагностика стратегий разбиения на блоки ​

chunker предоставляет SplitWithDiagnostics() (internal/infrastructure/chunker/strategy.go), возвращающий выбор цепочки стратегий, причины отклонения каждого tier и профиль документа; вместе с LOG_LEVEL=debug (логи chunker: tier %s rejected) это помогает диагностировать проблемы качества разбиения.

Скрипты обслуживания облачных образов ​

scripts/cloud-image/ служит для подготовки образов дистрибутива на выделенной одноразовой Linux-машине сборки. При обычном развёртывании используйте Установку и развёртывание; запускать эти скрипты не нужно.

  • prepare.sh скачивает файлы времени выполнения, соответствующие WEKNORA_REF, вытягивает образы и устанавливает службу systemd. Эта ссылка также задаёт версию образа — убедитесь, что соответствующий тег образа существует. Поставляемый с репозиторием systemd-юнит жёстко использует /opt/WeKnora; изменения только переменной каталога в скрипте недостаточно для переноса места установки.
  • cleanup.sh очищает данные, ключи, авторизацию SSH, логи и кэш Docker на машине сборки образов и выключает её; его влияние не ограничивается каталогом aihelpme.ru, поэтому применять его можно только на проверенной выделенной машине сборки.
  • firstboot.sh на новом инстансе генерирует ключи, записывает .env и запускает Compose; по завершении служба первого запуска отключается, а скрипт не удаляет себя.

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

Для диагностики первого запуска смотрите journalctl -u weknora-firstboot, /var/log/weknora-firstboot.log и состояние Compose в /opt/WeKnora. Файл .firstboot.done записывается после генерации ключей, но до запуска Compose; наличие маркера не означает работоспособность сервисов. При неудачном запуске сохраните сгенерированный .env и маркер, устраните причину и снова запустите Compose; удаление маркера и повторная генерация ключей могут привести к рассогласованию конфигурации с уже инициализированной базой данных.

Версия v0.8.3 · MIT License