Перейти к содержимому

Резервное копирование и восстановление

Две разные вещи для двух разных неприятностей.

Зашифрованный пакетЛокальная резервная копия по расписанию
Что в нейКонфигурация: мониторы и их учётные данные, правила, каналы, страницы статуса, учётные записи, токены.Вся база данных одним файлом, плюс secret.key.
Куда попадаетКуда вы её положите — она зашифрована выбранной вами парольной фразой./data/backups/, внутри того же тома.
От чего спасаетПотеря сервера, переезд на новое оборудование, чистая установка.Изменение, о котором вы жалеете через десять минут, неудачное обновление.
Чего в ней нетИстория метрик, состояние и история оповещений, журнал аудита, сессии.История метрик (vm/).

Ни то, ни другое не заменяет архив всего тома, если вам нужны и графики; об этом в конце страницы.

Settings → Backup → Download the bundle. Выберите парольную фразу не короче 16 символов — трёх слов достаточно — и подтвердите её. Скачиваемый файл — это обычный JSON с зашифрованным телом:

{
"format": "dumbmonit-backup",
"version": 1,
"created_at": "2026-09-22 19:04:11",
"source_version": "0.1.0-alpha.3",
"summary": { "targets": 12, "channels": 2, "rules": 41 },
"kdf": { "algorithm": "argon2id", "salt": "…", "m_cost": 32768, "t_cost": 3, "p_cost": 1 },
"cipher": "aes-256-gcm",
"payload": "…"
}

Заголовок остаётся читаемым, чтобы вы могли понять, что это за файл, ещё до ввода чего-либо. Всё остальное — включая адреса — находится внутри payload, зашифрованное AES-256-GCM ключом, производным от вашей парольной фразы через Argon2id. Восстановления нет: пакет с утерянной парольной фразой утерян.

РазделСодержимое
targetsМониторы: имя, тип, адрес, интервал, опции, родитель, ретранслирующий агент и учётные данные.
rulesПравила оповещений, включая встроенные, которые вы перенастроили или отключили.
rule_overridesПороги и исключения для отдельных мониторов.
channelsКаналы уведомлений, их настройки, их политика для канала и их секреты.
notify_policyГлобальная политика уведомлений (группировка, почасовой лимит, flapping, публичный URL).
silencesОкна обслуживания.
status_pagesПубличные страницы статуса и сервисы, перечисленные на каждой.
incidentsИнциденты и объявления об обслуживании с их обновлениями.
usersУчётные записи: имя пользователя, отображаемое имя, роль, связь с SSO, включена или нет.
agent_tokensТокены регистрации агентов, в виде хешей. Установленные агенты продолжают отправлять данные после восстановления.
api_tokensТокены API, в виде хешей. Существующие токены продолжают работать.
push_monitorsТокены heartbeat, чтобы URL, которые уже вызывают ваши задания cron, остались прежними.

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

По умолчанию учётные записи экспортируются без хеша пароля, секрета TOTP и кодов восстановления. Восстановленные учётные записи существуют с правильным именем и ролью, но никто не может войти под ними, пока администратор не задаст пароль — или пока они не войдут через SSO, которому ничего из пакета не нужно.

Включите Include account passwords and 2FA secrets, когда вы переносите экземпляр, а не копируете его конфигурацию. Хеш Argon2 в файле, который путешествует, можно атаковать офлайн сколько угодно долго; значение по умолчанию — безопасное.

История метрик (она живёт в VictoriaMetrics, а не в базе данных), состояние и история оповещений, базовые линии аномалий, журнал аудита, открытые сессии, регистрация и время последнего контакта агентов, а также кеши проб панелей Proxmox и Synology. Это наблюдения, а не настройки: они возвращаются сами.

И не секрет экземпляра. В этом суть: пакет несёт свои секреты перешифрованными вашей парольной фразой именно для того, чтобы его можно было восстановить там, где secret.key никогда не видели.

  1. Запустите новый контейнер и создайте первую учётную запись администратора на /setup с кодом установки, напечатанным в его логах. Эта учётная запись ваша; восстановление её не тронет.
  2. Settings → Backup → Restore a bundle. Выберите файл, введите парольную фразу и нажмите Check this backup.
  3. Прочитайте отчёт. В нём по разделам сказано, что будет создано, что будет обновлено, так как отличается от того, что уже есть, и что уже идентично, — плюс примечание для всего, что не удалось разместить, например правила, указывавшего на монитор, которого нет в пакете.
  4. Нажмите Restore for real.

Три правила, которые восстановление никогда не нарушает:

  • Ничто никогда не удаляется. Восстановление делает так, чтобы существовало то, что описывает пакет; всё, что есть в экземпляре сверх этого, остаётся.
  • Ничто никогда не дублируется. Каждый элемент сопоставляется по естественному ключу — тип + адрес для монитора, uid для правила, имя для канала, slug для страницы статуса. Повторное восстановление того же пакета сообщает, что всё уже идентично, и ничего не записывает.
  • Существующие учётные записи не трогаются. Учётная запись, имя пользователя которой уже есть, пропускается и никогда не перезаписывается: файл не должен иметь возможности изменить роль или пароль администратора, выполняющего восстановление.

Пробный прогон — это не имитация восстановления, это и есть восстановление, выполненное внутри транзакции, которая в конце откатывается. Отчёт не может ошибаться в том, что сделало бы применение.

Пакет, записанный более новым DumbMonit, отклоняется с фразой, которая так и говорит, — сначала обновитесь, потом восстанавливайте. Пакет, который был изменён или у которого неверная парольная фраза, тоже отклоняется: AES-GCM не отличает одно от другого, и сообщение тоже.

Оба маршрута требуют сессию администратора, а не токен API: токен живёт в скрипте, а скрипту незачем экспортировать все учётные данные экземпляра.

Окно терминала
# Sign in
curl -s -c jar -X POST https://localhost:8080/api/auth/login \
-H 'content-type: application/json' -H 'X-Requested-With: DumbMonit' \
-d '{"username":"admin","password":"…"}'
# Export
curl -s -b jar -X POST https://localhost:8080/api/backup \
-H 'content-type: application/json' -H 'X-Requested-With: DumbMonit' \
-d '{"passphrase":"three words are enough"}' -o backup.json
# Dry run, then apply
jq -n --slurpfile b backup.json \
'{bundle: $b[0], passphrase: "three words are enough", apply: false}' > restore.json
curl -s -b jar -X POST https://localhost:8080/api/backup/restore \
-H 'content-type: application/json' -H 'X-Requested-With: DumbMonit' \
-d @restore.json | jq

DumbMonit по расписанию записывает копию собственной базы данных, по умолчанию раз в день, храня последние семь, в /data/backups/:

/data/backups/dumbmonit-20260922-030000.db
/data/backups/dumbmonit-20260922-030000.key

Файл .db создаётся с помощью SQLite VACUUM INTO: это онлайн-копия, согласованная, записанная пока сервер продолжает работать, а не копирование файла, которое могло бы застать базу данных посреди записи. sqlite3 открывает её как есть, без журнала для воспроизведения. Файл .key рядом — это копия secret.key; вместе эта пара достаточна для восстановления экземпляра.

Они лежат в том же томе, что и база данных, поэтому они отменяют ошибку, но не потерянный диск. Копируйте их с машины, если вам нужно больше.

ПеременнаяПо умолчаниюНазначение
DUMBMONIT_BACKUP_ENABLED10, false, no или off, чтобы прекратить запись резервных копий по расписанию.
DUMBMONIT_BACKUP_DIR<data dir>/backupsКуда они записываются. Укажите второй том, чтобы пережить потерю первого.
DUMBMONIT_BACKUP_INTERVAL_HOURS24Часов между двумя копиями. Первая создаётся через один интервал после запуска, а не при запуске.
DUMBMONIT_BACKUP_KEEP7Сколько хранится. Самые старые удаляются вместе с их .key.

Ничего другого в каталоге никогда не затрагивается: ротируются только файлы с именами dumbmonit-<timestamp>.db и их .key.

Когда секрет экземпляра берётся из DUMBMONIT_SECRET, файла для копирования нет и он не записывается — храните это значение в менеджере паролей. Раздел Backup сообщает, в каком из двух случаев вы находитесь.

Каждый запуск публикует три ряда:

МетрикаЗначение
dumbmonit_instance_backup_last_success_secondsUnix-время последней успешной резервной копии. Неудачная попытка никогда его не обновляет.
dumbmonit_instance_backup_last_status1, если последняя попытка удалась, 0, если нет.
dumbmonit_instance_backup_size_bytesРазмер последнего записанного файла.

Встроенное правило DumbMonit backup did not run (instance_backup_missing) срабатывает, когда последний успех старше двух дней — одна пропущенная ночь может быть перезапуском, две — уже проблема. Ряд существует только после записи первой копии, поэтому экземпляру с отключённым расписанием об этом никогда не напоминают.

Settings → Backup показывает то же самое без MetricsQL: последний запуск и его успешность, хранимые файлы и их размер, а также Back up now, чтобы записать копию немедленно.

Остановите стек, верните файл под именем базы данных и восстановите ключ рядом с ней:

Окно терминала
docker compose stop
docker run --rm -v dumbmonit-data:/data alpine sh -c '
cp /data/backups/dumbmonit-20260922-030000.db /data/dumbmonit.db &&
cp /data/backups/dumbmonit-20260922-030000.key /data/secret.key &&
rm -f /data/dumbmonit.db-wal /data/dumbmonit.db-shm'
docker compose start

Удаление файлов -wal и -shm важно: они принадлежат базе данных, которую вы только что заменили, и SQLite попытался бы применить их к новой.

Чтобы прочитать резервную копию без восстановления, скопируйте её наружу и откройте с помощью sqlite3:

Окно терминала
docker run --rm -v dumbmonit-data:/data -v "$PWD:/out" alpine \
cp /data/backups/dumbmonit-20260922-030000.db /out/
sqlite3 dumbmonit-20260922-030000.db 'SELECT name, kind, address FROM targets;'

Учётные данные в этом файле остаются нечитаемыми без соответствующего secret.key.

Единственный способ сохранить и графики. Один именованный том, dumbmonit-data, содержит всё: базу данных, секрет, локальные резервные копии и данные VictoriaMetrics.

Окно терминала
docker compose stop
docker run --rm -v dumbmonit-data:/data -v "$PWD:/backup" alpine \
tar czf /backup/dumbmonit-data.tgz -C /data .
docker compose start

Для восстановления создайте том, распакуйте в него архив таким же образом, затем docker compose up -d.

Если важно место, --exclude=./vm делает архив небольшим: база данных и секрет — это настройка, vm/ — только история.

  1. Settings → Backup → Back up now — тридцать секунд, и в копию входит секрет.
  2. Скачайте также пакет, если обновление крупное или если вы переезжаете на другую машину.
  3. docker compose pull && docker compose up -d. Миграции выполняются при запуске.

Если что-то пойдёт не так, восстановите локальную копию и запустите предыдущий тег образа.