Salta ai contenuti

备份和恢复

Questi contenuti non sono ancora disponibili nella tua lingua.

两种不同的东西,用于两种不同的事故。

加密包定时本地备份
它包含什么配置:监控项及其凭证、规则、通道、状态页面、账户、令牌。整个数据库,作为一个文件,加上 secret.key。
它去哪里任何你放它的地方——它用你选择的密码加密。/data/backups/,在同一个卷内。
它能保护你免受什么丢失的服务器、移到新硬件、全新安装。你十分钟后后悔的更改、出错的升级。
它不包含什么指标历史、警报状态和历史、审计日志、会话。指标历史 (vm/)。

都不能替代整个卷的存档如果你想找回图表;那在这个页面的底部。

设置→备份→下载包。 选择至少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 内,用从你的密码通过Argon2id派生的密钥用AES-256-GCM加密。没有恢复:密码丢失的包丢失。

部分内容
targets监控项:名称、类型、地址、间隔、选项、父级、中继代理和凭证。
rules警报规则,包括你已调整或禁用的内置规则。
rule_overrides每个监控项的阈值和排除。
channels通知通道、其设置、其每个通道策略和其密钥。
notify_policy全局通知策略(分组、每小时上限、抖动、公共URL)。
silences维护窗口。
status_pages公共状态页面和每个页面列出的服务。
incidents事件和维护公告,带有其更新。
users账户:用户名、显示名称、角色、SSO链接、启用或否。
agent_tokens代理注册令牌,作为哈希。安装的代理在恢复后继续推送。
api_tokensAPI令牌,作为哈希。现有令牌继续工作。
push_monitors心跳令牌,所以你的cron作业已经调用的URL保持相同。

监控项与类型+地址匹配,这也是表格的唯一密钥:导入相同包两次永远不会创建任何东西的第二个副本。

默认情况下账户导出不包括其密码哈希、TOTP密钥或恢复代码。恢复后的账户存在着正确的名称和角色,但没有人可以用它们登录直到管理员设置密码——或直到他们通过SSO登录,这不需要包中的任何内容。

当你移动实例而不是复制其配置时,打开包括账户密码和2FA密钥。Argon2哈希在一个可以旅行的文件中会被离线攻击,只要攻击者喜欢;默认是安全的。

指标历史(那生活在VictoriaMetrics中,不在数据库中)、警报状态和历史、异常基线、审计日志、打开的会话、代理的注册和最后见、Proxmox和Synology面板的探针缓存。它们是观察,不是设置:它们自己回来。

而且不是实例密钥。那是关键点:包将其密钥重新加密在你的密码下正是为了它可以恢复到从未见过 secret.key 的地方。

  1. 启动新容器并在 /setup 创建第一个管理员账户,使用其日志中打印的设置代码。该账户是你的;恢复不会接触它。
  2. 设置→备份→恢复包。 选择文件,输入密码,并按检查该备份。
  3. 阅读报告。它逐部分说明什么会创建,什么会更新因为它与这里已有的不同,什么已经相同——加上笔记用于它无法放置的任何内容,如指向包不包含的监控项的规则。
  4. 按真正恢复。

恢复永远不会打破的三个规则:

  • 没有东西永远被删除。 恢复让包描述的存在;实例额外有的任何东西留下。
  • 没有东西永远被复制。 每项与其自然密钥匹配——监控项的类型+地址,规则的 uid,通道的名称,状态页面的slug。恢复相同包两次报告一切已相同并写入无。
  • 现有账户不被触及。 用户名已经在这里的账户被跳过,永不覆盖:文件不得能改变运行恢复的管理员的角色或密码。

干跑不是恢复的模拟,它是恢复,在最后被回滚的事务内运行。报告不能在应用会做什么上出错。

用更新的DumbMonit编写的包被拒绝,带一句说这个的句子——先升级,然后恢复。被修改的包或其密码错的包也被拒绝:AES-GCM不能区分两者,消息也不能。

两个路由都需要管理员会话,不是API令牌:令牌生活在脚本中,脚本无权导出实例的每个凭证。

Terminal window
# 登录
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":"…"}'
# 导出
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
# 干跑,然后应用
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 时没有文件要复制,没有被写——改为在你的密码管理器中保留该值。备份部分说哪两种情况你在其中。

每个运行发布三个序列:

指标含义
dumbmonit_instance_backup_last_success_seconds最后成功的备份的Unix时间戳。失败的尝试永不刷新它。
dumbmonit_instance_backup_last_status如果最后尝试成功为1,如果失败为0。
dumbmonit_instance_backup_size_bytes最后写的文件的大小。

内置规则DumbMonit备份未运行 (instance_backup_missing) 当最后成功超过两天前时触发——一个失误的夜晚可能是重启,两个是问题。序列仅在第一个备份被写后存在,所以一个关闭的调度实例永不被它烦扰。

设置→备份显示相同的东西不没有MetricsQL:最后运行及是否成功、保留的文件及其大小,以及立即备份立即写一个。

停止堆栈,将文件放回数据库的名称下,并在其旁恢复密钥:

Terminal window
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 打开它:

Terminal window
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数据。

Terminal window
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. 设置→备份→立即备份——三十秒,它包括密钥。
  2. 下载包如果升级是个大的,或如果你在移到另一台机器。
  3. docker compose pull && docker compose up -d。迁移在启动时运行。

如果出错,恢复本地备份并启动之前的镜像标签。