跳转至

配置

本页涵盖容器的环境变量、模板提供的挂载、通过 SSH 进行的虚拟机备份,以及异地设置。备份仓库路径在应用内部配置(设置,存储,备份路径),而不是通过环境变量。

环境变量

变量 是否必需 描述
APP_KEY 是 用于派生 restic 仓库密码的 32 字节十六进制密钥(64 个十六进制字符)。用 openssl rand -hex 32 生成。请妥善保管:丢失它将使加密备份无法恢复。
LIBVIRT_HOST 虚拟机和 ZFS 数据集需要 用于虚拟机备份、通过 SSH 连接的 Unraid 主机(默认 host.docker.internal;模板会预填一个 LAN-IP 占位符)。请使用您的 Unraid LAN IP,在自定义 br0.x 网络上为必需。 ZFS 数据集备份也使用它(模板字段 Host SSH: Address);占位值 192.168.x.x 视为未设置。
LIBVIRT_SSH_PORT 否 用于虚拟机备份的主机 SSH 端口(默认 22)。 模板字段 Host SSH: Port,ZFS 数据集也使用。
LIBVIRT_SSH_USER 否 用于虚拟机备份的主机上的 SSH 用户(默认 root)。 模板字段 Host SSH: User,ZFS 数据集也使用。
LIBVIRT_URI 否 完整的 libvirt 连接 URI,将原样使用,而不再由上方三个 LIBVIRT_* 变量拼接而成(此时这三个变量对连接字符串不再生效)。默认未设置。TrueNAS Scale 上需要用到它,因为其 libvirtd 监听在拼接形式无法表达的非标准套接字上:qemu+ssh://<user>@<truenas-host>/system?socket=/run/truenas_libvirt/libvirt-sock。参见 docs/vm-backup-ssh-setup.md 的 TrueNAS Scale 部分。 如果是 qemu+ssh:// URI,LIBVIRT_HOST、LIBVIRT_SSH_USER 和 LIBVIRT_SSH_PORT 中未设置的每一项都从中获取,BombVault 自己的 SSH 命令(NVRAM 传输、ZFS 数据集)也是如此。
PORT 否 HTTP 端口(默认 3000;仅在 HTTP_ONLY=true 时使用)。
HTTPS_PORT 否 HTTPS 端口(默认 3443;模板以 1:1 发布它,因此 WebUI 在 https://<ip>:3443 上应答)。
HTTP_ONLY 否 设为 true 以禁用自签名 HTTPS 监听器,仅提供纯 HTTP 服务(用于在一个终止 TLS 的反向代理之后)。
BIND_HOST 否 WebUI 监听的地址(默认 0.0.0.0,即所有接口)。在容器中请保持不设置,因为其发布的端口需要所有接口;127.0.0.1 适用于在 Docker 之外运行。健康检查也访问同一地址。
TRUSTED_PROXY 否 BombVault 前面反向代理的地址或 CIDR 网段,以逗号分隔(例如 192.168.20.11 或 10.0.0.0/8)。只有来自这些跳点的 X-Forwarded-For 才会被采信,登录限流随后按真实客户端分别计数,而不是把代理后面的所有人放进同一个桶。未设置(默认)表示谁都不信任:无条件采信的标头会让任何调用方自行挑选计数桶。
HOST_SOURCE_ROOT 否 挂载为 Host Data 的主机路径(默认 /mnt)。BombVault 会将 Docker 报告的绑定挂载来源转换为此挂载下的路径。仅在您挂载了不同的主机根目录时才更改。
DATA_ROOT_SEGMENTS 否 以逗号分隔的路径片段名称,用于将绑定挂载来源标记为备份数据(默认为 appdata,对应 Unraid 的 /mnt/user/appdata/<container> 约定)。当所列片段中的任意一个作为完整路径片段出现在某容器绑定挂载的主机来源中时,该挂载就会被自动选中用于备份,例如 DATA_ROOT_SEGMENTS=appdata,config 也会选中类似 .../config 的绑定挂载。关于查找容器数据文件夹的其他常驻方式,参见备份来源检测。
PLATFORM 否 强制指定 BombVault 认为自己运行在哪个平台上,而不进行自动检测:unraid、generic 或 truenas(默认未设置,会通过在闪存挂载下探测 dockerMan 标记来自动检测 Unraid,否则为 generic;无法识别的值同样回退为 generic,并记录到日志)。请在通用 Docker 主机或 TrueNAS Scale 上显式设置它,而不要依赖仅适用于 Unraid 的自动探测;通用 compose 文件正是这样做的。它会改变 appdata 回退约定、跨实例还原目标的默认值,以及是否会尝试仅适用于 Unraid 的通知/配套插件步骤(参见 internal/platform)。
BOMBVAULT_SELF_CONTAINER 否 BombVault 容器自身的名称,以便它绝不会备份(从而停止)自己。
BACKUP_MAX_HOURS 否 单次备份运行在被强制取消前可持有其域锁的最长挂钟小时数(一道防护,防止卡死的运行永久阻塞该域)。留空(默认)使用 48。对于非常大或缓慢的云备份可调高它(在上限处被取消的运行会以 context deadline exceeded 失败)。设为 0 可完全禁用该上限。
BACKUP_STALL_HOURS 否 备份在完全没有进展的情况下,被取消之前可持续的小时数。留空(默认)使用 2;设为 0 则绝不因停滞而取消。它是两道防护中更精细的一道,通常也是先触发的那一道:它关注的是是否仍有事情在发生,而不是运行已经花了多久,因此一个缓慢但健康的数 TB 备份不会被打扰,而卡在无响应共享上的备份会在几小时内而不是几天后被停止。在取消任何东西之前,静默 30 分钟后会先记录一条警告。扫描也算作进展:restic 遍历大型目录树时不写入任何字节,这一阶段通过它的文件和字节总数来监视,而不是通过已写入的字节。两个变量相互独立,BACKUP_MAX_HOURS 仍然约束备份本身之后的阶段(保留、统计、异地复制),那些阶段没有可监视的计数器。
DB_DUMP_MAX_HOURS 否 一次自动数据库转储在被停止前可以运行的小时数。留空(默认)使用 6;允许 1 到 48,并且该上限比 BACKUP_MAX_HOURS 低一小时(该值不足两小时时取其一半),好让长转储被自己的上限截断并如实上报,而不是把备份一起拖垮。不再有进展的转储会更早停止,在 BACKUP_STALL_HOURS 之后。被停止的转储只算它自己失败,容器备份继续进行。在 Unraid 上,用 Add another Path, Port, Variable 把该变量加到 BombVault 容器。
TZ 否 计划任务的时区(例如 Europe/Berlin)。 未设置时,所有计划均按 UTC 运行:设为 02:30 的计划将在 02:30 UTC 启动,而不是本地时间。 在 Unraid 上无需自行设置:系统会将自身时区传递给每个容器。启动日志会显示最终采用的时区。有夏令时的时区会在春季跳过一次运行,在秋季让一次运行执行两遍;UTC 不会出现这两种情况,但每年会有两次与您的本地时钟相差一小时。

挂载

按 CA 模板所示挂载 Docker 套接字、闪存(/boot)和 Host Data 根目录(/mnt)。备份的来源和目标都位于 Host Data 之下,且它以 slave 方式挂载,因此在容器启动后才挂载的远程共享(例如位于 /mnt/remotes 之下)无需重启即可可见。

ZFS 数据集备份同样需要这种模式:主机要在容器启动之后才挂载数据集的快照。参见 ZFS 数据集。

备份仓库路径默认为 /mnt/user/bombvault/{container,vms,flash,config,files,zfs},在首次备份时创建。可随时在设置,存储,备份路径中更改位置。每个路径字段旁还有一个内联的本地 / 远程开关:路径可以是一个 restic 远程(s3:...、rest:...、sftp:...、rclone:...)而不是本地文件夹,直接备份到那里,不另留本地副本;参见远程主仓库。

主机集成检查

容器启动后在 Web 界面打开 /spike。它会探测每个挂载和 CLI(Docker 套接字、libvirt、restic、qemu-img、rclone)并报告任何缺失的部分。

备份来源的自动识别

对每个容器,BombVault 会自行挑选要备份哪些绑定挂载和具名卷。只要符合下列任意一条,路径就会被采纳(结果随时可在该容器的 备份文件夹 中逐个覆盖):

  • 命中数据根目录片段: 绑定在宿主机上的来源,把 DATA_ROOT_SEGMENTS 里的某个片段作为完整的一级路径包含在内(默认只有 appdata)。
  • Docker 具名卷 一律纳入,因为它们没有可丢弃的对应物,也就没什么可过滤的,但仅当该卷在宿主机上的真实存储路径本身能通过 Host Data 挂载抵达时才算,这和 BombVault 备份的其他宿主机路径条件完全一致。默认的本地卷驱动会把卷放在守护进程自己的数据根目录下,即未做修改时的 /var/lib/docker/volumes/<name>/_data(可用 docker info -f '{{.DockerRootDir}}' 查看)。这个位置并不在通用 docker-compose.yml 默认使用的那个只含单个目录的窄 Host Data 挂载里。抵达不到的卷会被静默跳过,这不算错误。要在通用主机上真正备份具名卷,请把 Host Data(以及 HOST_SOURCE_ROOT)指向一个同时覆盖 Docker 数据根目录的共同上级目录,取舍见 compose 文件里的 Host Data 注释(Unraid 出于同样的原因,直接挂载整个 /mnt,也就是它自己的顶层通用约定,从而绕开了这个问题)。
  • Docker Compose 项目目录: 若容器带有标准标签 com.docker.compose.project.working_dir(由 docker compose up 自动设置),该目录也会一并加入,无论是否有绑定命中了数据根目录片段。
  • 用标签 bombvault.data 覆盖: 给容器设上标签 bombvault.data=true,即可纳入它的全部绑定挂载,适用于上面两条约定都抓不到的布局(例如没有 Compose 项目、只有单个 /srv/plex/config 绑定)。除 false 之外任何非空值都算作真;没有该标签或 bombvault.data=false 则什么也不改变。
  • 标签 bombvault.dbdump: 给容器设置 bombvault.dbdump=false 即可关闭它的自动数据库转储(0、no、off 效果相同),或者写上引擎名(postgres、mysql、mariadb),让 BombVault 转储它自己认不出来的容器。标签优先于容器卡片上的开关,而在 Unraid 上通常就用那个开关。

安全模型

对主机的等同于 root 的控制权

通过 Docker 套接字,BombVault 可以停止、删除和重新创建容器并读写 appdata,而对于虚拟机备份,它会通过 SSH 登录主机(qemu+ssh://,默认 root)以运行 virsh。任何能访问其 Web 界面的人实际上都拥有主机的 root 权限。

  • 可选的密码保护(设置、安全):设置密码即要求登录,清空即关闭。默认关闭,面向可信局域网使用。密码以 Argon2id 存储在一个用 APP_KEY 加过胡椒的值之上,因此被复制的 /config 没有密钥毫无价值,有密钥也很难快速破解。新密码至少需要 12 个字符;已有的较短密码在更改之前仍然可用。会话经过签名(由 APP_KEY 派生的 HMAC),更改密码会使其失效;登录被限制为每个客户端每分钟五次失败。
  • 两步验证(设置):在密码之外再用身份验证应用的时间码,并在开启时一次性发放八个一次性恢复码。共享密钥用 APP_KEY 加密存储,关闭时需要一个当前有效的验证码。
  • 通行密钥(WebAuthn)在设置密码后会出现在单独的卡片上。它与密码并用,从不取代密码,因此即使删除所有通行密钥也不会把任何人锁在外面。它需要一个真实的域名,以及浏览器信任的证书。默认的 https://<ip>:3443 正是 WebAuthn 会拒绝的形式,因此卡片会直接说明这一点,而不是提供一个注定失败的按钮。
  • 更改需要 JSON。 任何更改内容的请求都必须发送 Content-Type: application/json,并且不能被浏览器标记为跨站请求,这样其他网站上的页面就无法借您的浏览器修改某个局域网地址上的设置。调用 API 的脚本会发送这个请求头;其他请求一律以 415 拒绝。
  • 由于该门是可选启用的,未设置时整个界面和 API(包括异地设置、篡改测试路由和恢复工具包)对任何能访问该端口的人都可访问。在使用异地、不可变备份或加密后就启用该门。
  • 请仅在受信任、未对外暴露的网络上运行 BombVault。对于远程访问,请将它置于一个添加了身份验证和 TLS 的反向代理之后。响应携带基线安全头(CSP、nosniff、X-Frame-Options、Referrer-Policy)。
  • 在反向代理后面,每个请求携带的都是代理的地址,因此不设置 TRUSTED_PROXY 时登录限流会把所有客户端算作一个,攻击者的失败也会把你锁在门外。在 TRUSTED_PROXY 中写明代理,即可恢复按客户端计数。
  • BombVault 前面的反向代理必须把 Authorization 或 X-API-Key 请求头转发到 /mcp,并且不能缓冲响应,否则助手无法连接。见 MCP 服务器。
  • 在存在密钥或开启通过 OAuth 登录之前,MCP 端点 /mcp 一律返回 404;即使关闭了登录密码,它也会向每个客户端索要密钥或令牌,没有任何地址例外,localhost 也不例外。它没有还原或删除工具,而还原配置备份会撤销所有密钥。见 MCP 服务器。
  • 使用 HTTP_ONLY=true 时,会话 cookie 会失去其 Secure 标志(必须如此,才能在纯 HTTP 上工作),因此只有在保密性重要时才在一个终止 TLS 的代理之后启用密码。
  • 虚拟机备份的 SSH 连接在首次连接时信任主机密钥(TOFU)并此后固定它。如果您的容器到主机的路径不受信任,请带外验证主机的密钥。
  • 启用加密时(设置;默认开启),备份由 restic 加密,密钥从 APP_KEY 派生。

MCP 服务器

MCP 服务器不需要任何环境变量。在 设置、集成、MCP 服务器 中创建密钥即可开启,它在与网页界面相同的端口上响应 /mcp(例如 https://192.168.1.10:3443/mcp)。没有有效密钥时,该路径返回 404。客户端、证书和限制见 MCP 服务器。

通过 SSH 进行虚拟机备份

BombVault 不挂载任何 libvirt 路径即可备份 KVM/libvirt 虚拟机。它通过 SSH(qemu+ssh://)在主机上运行 virsh,因此它绝不会影响您的主机虚拟机管理器。

在 Unraid 上,把主机的 libvirt 套接字挂载进容器并不可靠:这些路径归虚拟机管理器所有,切换"Enable VMs"可能导致 libvirt 无法启动。SSH 密钥授予的是主机上的 root 权限,与 BombVault 已在使用的 Docker 套接字属于同一信任级别。

快速设置:

  1. 设置,集成,主机 SSH: 复制显示的公钥。
  2. 将它追加到 Unraid 的 /root/.ssh/authorized_keys(也会持久化到闪存,以便重启后仍然有效)。
  3. 点击测试连接。

模板会添加 --add-host=host.docker.internal:host-gateway,以便容器能访问主机。如果该名称无法解析(例如当容器运行在自定义 br0.x 网络上时),请将 LIBVIRT_HOST 设置为您的 Unraid LAN IP。如果您更改了 Unraid 的 SSH 端口,请相应设置 LIBVIRT_SSH_PORT。实时快照额外需要虚拟机中的 qemu guest agent,以及位于 /mnt/cache(而非 /mnt/user)上的磁盘。

完整的虚拟机设置与网络指南

完整的逐步指南(SSH 启用、持久化密钥授权、自定义网络和 VLAN 路由、每台虚拟机的方式以及主机侧疑难解答)位于 GitHub 上的 docs/vm-backup-ssh-setup.md。

异地设置

在设置,异地页面设置异地副本。完整的工作流程(不可变/append-only、篡改测试和 DR 演练)参见异地与恢复。简而言之:

  • 后端: SMB/CIFS 和 NFS(挂载共享并将备份路径指向它)、无需 rclone 的原生 restic 后端(s3:...、rest:http://host:8000/repo、sftp:user@host:/repo),或任意 rclone 远程(rclone:<remote>:<bucket>/path)。Backblaze B2 在这里没有原生后端:请通过其 S3 端点访问(s3:https://s3.<region>.backblazeb2.com/<bucket>/<path>),并将密钥 ID 和应用密钥作为 S3 凭据填写。
  • 共享云凭据以加密方式存储在设置,云访问,共享云凭据之下。
  • SSH 目标无需在对端安装任何东西。 sftp: 只需要一个 SSH 服务器。将来自设置,集成,主机 SSH的公钥(也位于 /config/ssh/id_ed25519.pub)添加到目标用户的 ~/.ssh/authorized_keys。
  • 异地复制: BombVault 在(通常是本地的)主仓库之外,以尽力而为的方式用 restic copy 复制新快照。每个域都有各自的异地计划,外加一个立即复制按钮。
  • 每个域可有多个异地目标: 每个域都可以同时复制到多个异地目标。在设置,异地添加额外目标,每个目标都有各自的仓库、S3 存储类别、append-only 标志、保留和增长预算;它们全都按该域的异地计划复制。一个现有的单一异地设置会作为第一个目标沿用下来。
  • 目标: 异地目标在 设置、异地、目标 下一次性设置,通过一个列出所有受支持服务的向导完成。参见目标。
  • 每个项目的存放位置: 每个容器、虚拟机和文件集都会点亮本地以及获得其备份的目标。对于没有自己选择的项目,由 设置、存储、存放位置默认值 按域设定。参见每个项目的存放位置。
  • 按来源的保留: 本地和异地策略均位于设置,保留(将异地部分全部留为零则从不自动清理异地快照)。本地保留 和 异地保留 两张卡片都有 按来源设置保留规则,可以为容器、虚拟机、闪存、文件夹、ZFS 或自备份的本地备份和异地仓库分别设置自己的保留规则。没有自己规则的来源沿用共用规则,备份后的保留、异地复制、手动清理和保留预览都使用所处理来源的规则。其他异地目标保留在设置,异地中为它们设定的规则。
  • 带宽限制: 在设置,异地之下限制 restic 的上传/下载速率。
  • 串流优先: 在 设置,异地 中选择媒体服务器(Plex、Jellyfin 和 Emby 会按镜像名预先选中)、视为串流的发送速率、串流期间的上传限制,以及串流结束后多久恢复常规限制。
  • 冷存储与归档存储类别(S3): 对于原生 S3 异地仓库,选择一个可还原读取的层级(Standard、Standard-IA、One Zone-IA、Intelligent-Tiering、Glacier Instant Retrieval)。rclone 远程在 rclone 配置中设置其类别。
  • 以远程代替本地作为主仓库: 一个域的备份路径本身就可以是上述后端之一,没有本地副本,也没有复制步骤。内联的本地/远程开关及其带宽、append-only、增长预算等安全设置,参见远程主仓库。

异常

异常检测在 设置,完整性 的 异常 卡片中设置。每个控件在您更改后立即保存,检测关闭时开关下方的三个控件会隐藏。

设置 默认值 作用
检测异常 开启 将每次备份与对象自己的历史进行比较。关闭后不再检查任何新内容,异常 条目会从侧边栏消失;卡片仍然链接到以前的发现。
灵敏度 均衡 严格会报告较小的变化,宽松只报告大的变化。
发送通知的范围 仅严重的发现 通过 通知 中设置的渠道发送消息的最低严重程度。重复失败的备份和转储以及失败的计划恢复检查已经会发送自己的消息,不会发送两次。
当源急剧缩小或被重写时保留旧备份 开启 只要对象有关于几乎为空的源、大幅缩小或大部分数据被重新存储的未关闭发现,保留策略和清理就不会动它的旧备份。确认该发现或将其标记为预期之内即可释放它们。

每个对象都可以有自己的灵敏度和通知最低级别。可在 异常 页面设置:有未关闭发现的对象在其卡片的 监控 下设置,其他对象从 没有未处理项 卡片打开;也可在对象自己的面板中设置:容器的文件夹部分和虚拟机的设置(两者都在高级模式下)、文件夹集的文件夹编辑器,以及 闪存 和 自我备份 页面。ZFS 对象的这些设置在 ZFS 页面上该对象的编辑器里,适用于其树中的每个数据集。

可移植设置(导出与导入)

设置,系统页面上的导出 / 导入设置卡片会将您的整套 BombVault 配置(域设置、异地目标、计划、保留、通知)写入一个可移植的 JSON 文件,您可以在另一个实例上导入它,因此迁移到新机器或克隆一套配置不再意味着要手动重新录入一切。导入会显示预览并要求确认,且绝不会触动您的备份数据或历史。

导出文件可能包含凭据

您可以选择是否在文件中包含异地、通知和 MQTT 代理凭据。包含凭据时,导出文件与您的恢复工具包一样敏感,因此请将它存放在安全的地方。不包含凭据时,该文件只保存非机密的设置。