Backrest v1.14.1 配置参数详解

Backrest v1.14.1 安装路径、启动参数与 config.json 逐项详解:全局/仓库/计划/调度/保留策略/钩子通知,每个关键参数附修改与验证闭环,全程实测。

Backrest配置参数详解数据备份Restic2026/10/26

Backrest v1.14.1 配置参数详解

目标:把 Backrest v1.14.1 的安装路径、启动参数与 config.json 逐项讲透——每个关键参数都给出「含义 + 修改方法 + 验证闭环」。本文全部命令与回显已在 Ubuntu 22.04.5 LTS (x86_64) 环境实测通过(Backrest v1.14.1 + restic v0.19.1)。

一、环境信息

  • 操作系统:Ubuntu 22.04.5 LTS (x86_64),systemd 运行;
  • Backrest:v1.14.1(commit 875c9cb51e626a75276a64da42c6a9ec0695010a),restic v0.19.1(托管模式);
  • 服务单元:/etc/systemd/system/backrest.service,运行用户 admin;
  • 配置文件:/home/admin/.config/backrest/config.json;
  • 数据目录:/home/admin/.local/share/backrest/;
  • 演示仓库:local-demo(URI /srv/backups/local-demo,口令 q1w2e3r4);演示计划:demo-docs(路径 /srv/demo-data)。

二、前置条件

  • Backrest v1.14.1 已安装并 systemctl is-active backrest 为 active(安装步骤见站内部署篇:《Ubuntu 22.04 安装 Backrest v1.14.1 指南》);
  • 熟悉 JSON 语法与 systemd 基本操作;
  • 改配置前建议先备份一份:cp /home/admin/.config/backrest/config.json ~/config.json.bak(该文件同时保管仓库加密密码,属关键资产)。

三、配置查看与修改方式

3.1 三种修改通道

通道适用场景生效方式
直接编辑 config.json初始化预置、凭据重置、批量调整重启服务 systemctl restart backrest
gRPC 接口 SetConfig脚本化/自动化修改立即生效(服务热加载)
WebUI 表单日常运维立即生效

⚠️ 注意:Backrest 采用乐观锁机制——配置文件中的 modno 字段是配置版本号,每次修改自动加一。通过接口修改时请求必须携带当前 modno,否则服务拒绝写入。

3.2 读取当前配置(GetConfig)

curl -s -X POST http://127.0.0.1:9898/v1.Backrest/GetConfig \
  -H "Content-Type: application/json" -H "Connect-Protocol-Version: 1" \
  -d '{}'

实测回显(输出节选,实测首尾):

{"modno":4,"version":6,"instance":"backrest-server","auth":{"disabled":true,"users":[{"name":"admin","passwordBcrypt":"…"}]},"repos":[…],"plans":[…],"sync":{"identity":"…"}}

3.3 接口修改(SetConfig)与乐观锁

通过接口修改的正确姿势:先 GetConfig 拿到完整配置 → 在内存中改字段 → 原样 SetConfig(modno 一并回传)。实测把 demo-docs 计划的钩子命令从不可写路径改到可写路径:

curl -s -X POST http://127.0.0.1:9898/v1.Backrest/GetConfig \
  -H "Content-Type: application/json" -H "Connect-Protocol-Version: 1" \
  -d '{}' | python3 -c "
import sys, json
cfg = json.load(sys.stdin)
cfg['plans'][0]['hooks'][0]['actionCommand']['command'] = 'echo hook-fired-at-$(date +%F_%T) >> /srv/backups/hook-ran.log'
print(json.dumps(cfg))" | curl -s -X POST http://127.0.0.1:9898/v1.Backrest/SetConfig \
  -H "Content-Type: application/json" -H "Connect-Protocol-Version: 1" -d @- -w "\n[%{http_code}]\n"

实测回显:

{"modno":4,...,"plans":[{"id":"demo-docs",...,"hooks":[{"conditions":["CONDITION_SNAPSHOT_SUCCESS"],"onError":"ON_ERROR_IGNORE","actionCommand":{"command":"echo hook-fired-at-$(date +%F_%T) >> /srv/backups/hook-ran.log"}}]}]}
[200]

若请求携带的 modno 不是当前值,服务返回乐观锁冲突(实测回显):

{"code":"aborted","message":"config modno mismatch, reload and try again"}

重新 GetConfig 后带上最新 modno 重试即可。

3.4 修改后验证

钩子修改后的闭环验证:立即触发一次备份,确认钩子日志出现新格式记录:

curl -s -X POST http://127.0.0.1:9898/v1.Backrest/Backup \
  -H "Content-Type: application/json" -H "Connect-Protocol-Version: 1" \
  -d '{"value":"demo-docs"}' && sleep 9 && cat /srv/backups/hook-ran.log

实测回显:

{}hook-fired-at-2026-10-26_08:28:24

四、安装路径与启动参数总览

4.1 安装路径速查表

路径内容来源
/usr/local/bin/backrest主程序二进制install.sh
/usr/local/share/backrest安装摘要声明的 UI 资源路径(资源实际内嵌于二进制)install.sh
~/.config/backrest/config.json全部配置(仓库/计划/钩子/用户)首次运行生成
~/.local/share/backrest/restic托管的 restic 二进制首次运行自动下载
~/.local/share/backrest/oplog.sqlite操作日志数据库首次运行生成
~/.local/share/backrest/processlogs/backrest.log服务进程日志首次运行生成
~/.local/share/backrest/install.lock安装互斥锁restic 安装期存在
/etc/systemd/system/backrest.servicesystemd 服务单元install.sh

4.2 启动参数与环境变量对照(backrest --help 实测全文)

/usr/local/bin/backrest --help

实测回显:

Usage of /usr/local/bin/backrest:
  -bind-address string
        (env $BACKREST_PORT) address and port to serve the UI and API (default "127.0.0.1:9898")
  -config-file string
        (env $BACKREST_CONFIG) path to config file (default $XDG_CONFIG_HOME/backrest/config.json or /etc/backrest/config.json if exists)
  -data-dir string
        (env $BACKREST_DATA_DIR) path to data directory (default $XDG_DATA_HOME/.local/backrest)
  -install-deps-only
        install dependencies only. will exit after completion.
  -multihost-heartbeat-interval duration
        (env $BACKREST_MULTIHOST_HEARTBEAT_INTERVAL) interval to send heartbeats to the multihost connection manager (default 10m0s)
  -restic-cmd string
        (env $BACKREST_RESTIC_COMMAND) path to restic binary (default: a backrest managed version of restic will be installed and updated automatically.)
  -tray
        show tray icon (may not be supported on all systems)
  -version
        print version and exit

参数与环境变量的对应关系与实测说明:

命令行参数环境变量默认值实测说明
-bind-addressBACKREST_PORT127.0.0.1:9898服务单元中写入 0.0.0.0:9898 即开放远程访问
-config-fileBACKREST_CONFIG$XDG_CONFIG_HOME/backrest/config.json运行用户为 admin 时即 /home/admin/.config/backrest/config.json
-data-dirBACKREST_DATA_DIR$XDG_DATA_HOME/.local/backrest帮助文案与实际落盘不一致:实测数据实际落在 $XDG_DATA_HOME/backrest(即 /home/admin/.local/share/backrest/),以实际为准
-restic-cmdBACKREST_RESTIC_COMMAND托管模式自动安装默认使用 ~/.local/share/backrest/restic,可指向自备的 restic 路径
-tray—关闭桌面托盘模式
-multihost-heartbeat-intervalBACKREST_MULTIHOST_HEARTBEAT_INTERVAL10m0s多主机心跳间隔

💡 说明:生产环境最常用的做法不是改命令行,而是在 systemd 单元的 [Service] 段加 Environment="BACKREST_PORT=…" 等变量,与 install.sh 生成的单元写法保持一致。

五、config.json 核心参数分类详解

5.1 全局参数

实测环境当前配置的顶层结构(cat /home/admin/.config/backrest/config.json,输出节选):

{
  "modno": 4,
  "version": 6,
  "instance": "backrest-server",
  "auth": {
    "disabled": true,
    "users": [
      { "name": "admin", "passwordBcrypt": "$2a$10$NilNy2FBu/oteYAZScO5v.Ue4WrMLu/S5fEjvW9GYoiYFjGU20gjS" }
    ]
  },
  "repos": [ … ],
  "plans": [ … ]
}
参数类型/值含义与实测行为
modno整数配置版本号(乐观锁)。服务每次保存自动加一;接口修改必须回传当前值,否则报 config modno mismatch
version6配置结构版本号,服务自行维护,勿手改
instance字符串本机实例 ID,写入快照标签 created-by:(实测快照标签为 created-by:backrest-server)。官方文档提示:初始化后不可通过界面修改
auth.disabled布尔true 关闭认证(适合本机使用或前置反代认证);false 强制登录。实测 true 时所有接口匿名可用,改回 false 后匿名调用立即返回 {"code":"unauthenticated","message":"No Authorization Header provided"}
auth.users[].name字符串登录用户名
auth.users[].passwordBcrypt字符串bcrypt 哈希($2a$ 前缀)。推荐用服务端接口 v1.Authentication/HashPassword 生成(请求 {"value":"你的口令"},响应 value 字段为哈希的 base64,解码后写入),保证与校验逻辑兼容

⚠️ 注意:关闭认证的前提是监听地址仅限本机或已由反向代理统一认证;0.0.0.0 监听 + 认证关闭等于把备份仓库口令暴露在网络上。

5.2 仓库参数(repos)

实测仓库定义(来自 5.1 的配置文件):

"repos": [
  {
    "id": "local-demo",
    "uri": "/srv/backups/local-demo",
    "guid": "127f8961da1db8eaf5eb921bc30f43e054f84b3a49808e62d8d10513ed4b9280",
    "password": "q1w2e3r4",
    "autoInitialize": true,
    "autoUnlock": true
  }
]
参数类型含义与实测行为
id字符串仓库名,创建后不可改;计划通过它引用仓库
uri字符串restic 仓库地址。本地路径直接写目录;远端支持 s3:bucket/prefix、b2:bucket、gs:bucket:/、sftp:user@host:/path、rclone:remote:path 等 restic 全系后端
guid字符串仓库全局唯一 ID(对应 restic 仓库 config 中的 id),初始化后由服务回填,勿手改
password字符串仓库加密密码,明文存于配置由 Backrest 保管;调 restic 时自动注入(这正是「restic 密码托管」的含义——手动 CLI 操作同一仓库时必须自行带 RESTIC_PASSWORD 环境变量)
env字符串数组传给 restic 的额外环境变量,远端后端凭证写这里(如 S3 的 AWS_ACCESS_KEY_ID=…、AWS_SECRET_ACCESS_KEY=…,B2 的 B2_ACCOUNT_ID=…、B2_ACCOUNT_KEY=…)
flags字符串数组附加到 restic 命令的旗标(如 --no-lock、-o sftp.args="-i /path/to/key"、--limit-upload 1000)
autoInitialize布尔仓库不存在时自动 restic init。实测开启后首次启动自动建仓并回填 guid,日志输出 auto-initializing repo {"repo": "local-demo"}
autoUnlock布尔遇到残留锁文件时自动 restic unlock,避免运维介入
prunePolicy对象仓库级自动 prune 策略,字段见六、6.3
checkPolicy对象仓库级自动 check 策略,字段见六、6.4
hooks数组仓库级钩子(作用于该仓库的全部操作),字段结构同计划级钩子,见七

5.3 计划参数(plans)

实测计划定义(来自 5.1 的配置文件):

"plans": [
  {
    "id": "demo-docs",
    "repo": "local-demo",
    "paths": ["/srv/demo-data"],
    "schedule": { "cron": "*/5 * * * *" },
    "retention": { "policyKeepLastN": 3 },
    "hooks": [ … ]
  }
]
参数类型含义与实测行为
id字符串计划名,创建后不可改;快照标签 plan:demo-docs 即来源于此
repo字符串目标仓库 id,创建后不可改
paths字符串数组备份的目录/文件绝对路径
excludes字符串数组排除的 glob 模式(如 *node_modules*)
iexcludes字符串数组大小写不敏感的排除模式
schedule对象备份调度,三种形态见六、6.1
retention对象快照保留策略,三种形态见六、6.2
hooks数组计划级钩子,见七
backup_flags字符串数组备份命令的额外旗标
skipIfUnchanged布尔无变化时跳过备份(生成 SKIPPED 事件)

六、计划与策略参数详解

6.1 调度参数(schedule)

schedule 是四选一加时钟口径的结构(实测使用 cron):

形态字段说明
禁用"disabled": true不自动调度
cron 表达式"cron": "*/5 * * * *"标准 5 段 cron;官方推荐用 crontab.guru 校验写法
按天间隔"maxFrequencyDays": 1距上次运行不足 N 天则不跑
按小时间隔"maxFrequencyHours": 6距上次运行不足 N 小时则不跑
时钟口径"clock": "CLOCK_DEFAULT / CLOCK_LOCAL / CLOCK_UTC / CLOCK_LAST_RUN_TIME"壁钟本地/UTC/以上次运行时间为基准

修改 → 验证闭环:把 cron 设为 */5 * * * * 后,实测调度器把任务排到下一个整 5 分钟点:

Oct 26 08:25:59 backrest-server backrest[3748]: 2026-10-26T08:25:59.727Z        INFO        scheduled task        {"task": "backup for plan \"demo-docs\"", "runAt": "2026-10-26T08:30:00Z"}
Oct 26 08:30:01 backrest-server backrest[3748]: 2026-10-26T08:30:01.500Z        INFO        running task        {"task": "backup for plan \"demo-docs\"", "runAt": "2026-10-26T08:30:01Z"}

6.2 保留策略参数(retention)

三选一:

形态字段说明
按数量"policyKeepLastN": 3保留最近 N 个快照
按时间桶"policyTimeBucketed": {"hourly": 24, "daily": 7, "weekly": 4, "monthly": 12, "yearly": 3, "keepLastN": 5}各时间桶各留几份,keepLastN 无条件兜底
全保留"policyKeepAll": true永不 forget

修改 → 验证闭环:实测 policyKeepLastN: 3 生效过程——每次备份成功后自动触发 forget 任务:

{"id":"5","status":"STATUS_SUCCESS","operationForget":{"planId":"demo-docs","repoGuid":"127f8961…","policy":{"policyKeepLastN":3},"startTimeMs":"1793003228754","endTimeMs":"1793003228897"}}

随着 cron 连续备份,仓库内快照数稳定为 3,最早的两个快照(c73363b1…、3f0eb479…)被裁掉,此后用 restic CLI 直接恢复旧 ID 会报 failed to find snapshot(该坑实录见部署篇十、10.5)。

6.3 仓库级自动 prune(prunePolicy)

字段类型说明
schedule同 6.1 的 schedule何时允许跑 prune
maxUnusedBytes整数未引用数据超过该字节数即触发 prune
maxUnusedPercent小数未引用数据超过该百分比即触发 prune

💡 说明:forget(裁快照引用)与 prune(清除未引用数据块)是两步。实测不配 prunePolicy 时,通过界面/接口的 DoRepoTask(TASK_PRUNE)手动触发同样有效,实测任务 STATUS_SUCCESS。

6.4 仓库级自动 check(checkPolicy)

字段类型说明
schedule同 6.1 的 schedule何时允许跑 check
structureOnly布尔只校验仓库结构,不读数据包
readDataSubsetPercent小数抽样读取指定百分比的数据包校验

实测手动 check 任务(DoRepoTask TASK_CHECK)返回 STATUS_SUCCESS。

七、钩子与通知参数详解

7.1 钩子结构

钩子挂在计划(或仓库)上,结构为「触发条件 + 失败处理 + 动作」三段:

"hooks": [
  {
    "conditions": ["CONDITION_SNAPSHOT_SUCCESS"],
    "onError": "ON_ERROR_IGNORE",
    "actionCommand": {
      "command": "echo hook-fired-at-$(date +%F_%T) >> /srv/backups/hook-ran.log"
    }
  }
]

7.2 触发条件(conditions,可多选)

枚举值触发时机
CONDITION_ANY_ERROR任意操作出错
CONDITION_SNAPSHOT_START备份开始
CONDITION_SNAPSHOT_END备份结束(成功或失败)
CONDITION_SNAPSHOT_SUCCESS备份成功
CONDITION_SNAPSHOT_ERROR备份失败
CONDITION_SNAPSHOT_WARNING备份完成但有警告
CONDITION_SNAPSHOT_SKIPPED备份被跳过(如无变化)
CONDITION_PRUNE_START / _ERROR / _SUCCESSprune 生命周期
CONDITION_CHECK_START / _ERROR / _SUCCESScheck 生命周期
CONDITION_FORGET_START / _ERROR / _SUCCESSforget 生命周期

7.3 失败处理(onError)

枚举值行为
ON_ERROR_IGNORE忽略钩子错误,继续
ON_ERROR_CANCEL取消当前操作并跳过后续钩子
ON_ERROR_FATAL判定操作失败并终止后续钩子
ON_ERROR_RETRY_1MINUTE / ON_ERROR_RETRY_10MINUTES按 1/10 分钟重试
ON_ERROR_RETRY_EXPONENTIAL_BACKOFF指数退避重试,上限 1 小时

7.4 动作类型(oneof 八选一)

字段说明关键子字段
actionCommand执行本地命令(实测通过)command:sh 命令串,支持 $(date …) 等展开,以服务用户身份运行
actionWebhook通用 HTTP 通知webhookUrl、method(GET/POST)、template
actionDiscordDiscord 频道推送webhook 地址等
actionGotifyGotify 推送地址与令牌
actionSlackSlack 推送webhook 地址
actionShoutrrrShoutrrr 统一 URL 推送shoutrrr URL(支持 Telegram/邮件等数十端)
actionHealthchecksHealthchecks.io 心跳检查项 URL
actionTelegramTelegram 推送群组与令牌

修改 → 验证闭环(命令钩子,实测全程):配置七、7.1 的钩子后重跑备份,/srv/backups/hook-ran.log 出现 hook-fired-at-2026-10-26_08:28:24。再做一个错误钩子的反向验证:为坏路径计划挂 CONDITION_ANY_ERROR 钩子,备份必然失败,观察钩子是否照常触发:

cat /srv/backups/hook-error.log

实测回显:

error-at-2026-10-26_08:32:30

同时备份接口返回失败详情(实测回显):

{"code":"internal","message":"Backup failed for plan \"broken-path\": path /srv/does-not-exist does not exist: stat /srv/does-not-exist: no such file or directory"}

⚠️ 注意:钩子命令与 restic 全部以服务用户(本例 admin)身份运行。实测把输出重定向到 root 属主的 /srv/hook-ran.log 即触发 exit status 2,把目标改到 admin 可写目录后恢复——为钩子设计落点时先 chown 服务用户可写。

八、生产配置模板

以下模板汇总本文全部实测参数,可直接替换关键字段使用(演示口令与路径按需修改,并确保口令异地另存):

{
  "modno": 1,
  "version": 6,
  "instance": "prod-backrest-01",
  "auth": {
    "disabled": false,
    "users": [
      { "name": "admin", "passwordBcrypt": "$2a$10$<由 HashPassword 接口生成>" }
    ]
  },
  "repos": [
    {
      "id": "prod-repo",
      "uri": "/srv/backups/prod-repo",
      "password": "q1w2e3r4",
      "autoInitialize": true,
      "autoUnlock": true,
      "prunePolicy": { "schedule": { "maxFrequencyDays": 7 }, "maxUnusedPercent": 10 },
      "checkPolicy": { "schedule": { "maxFrequencyDays": 30 }, "readDataSubsetPercent": 5 }
    }
  ],
  "plans": [
    {
      "id": "prod-docs",
      "repo": "prod-repo",
      "paths": ["/srv/appdata"],
      "excludes": ["*.tmp", "*node_modules*"],
      "schedule": { "cron": "0 2 * * *", "clock": "CLOCK_LOCAL" },
      "retention": { "policyTimeBucketed": { "daily": 7, "weekly": 4, "monthly": 6, "keepLastN": 10 } },
      "hooks": [
        {
          "conditions": ["CONDITION_SNAPSHOT_ERROR", "CONDITION_ANY_ERROR"],
          "onError": "ON_ERROR_IGNORE",
          "actionShoutrrr": { "url": "telegram://<token>@telegram?chats=<chat-id>" }
        }
      ]
    }
  ]
}

模板要点:认证保持开启;远端仓库把凭证写进 repos[].env;保留策略用时间桶 + keepLastN 兜底;错误钩子接通知渠道(actionShoutrrr 的 URL 形式由 Shoutrrr 官方库定义,改前先用命令钩子本地验证触发链路)。

九、常见问题(FAQ)

9.1 接口改配置报「config modno mismatch」

接口修改必须先 GetConfig 取最新完整配置(含 modno),改字段后原样回传;报错即说明请求里的 modno 落后于当前值,重取重传即可(实测报错原文见三、3.3)。

9.2 手改配置后不生效

直接编辑文件后必须重启服务:

systemctl restart backrest && systemctl is-active backrest

实测回显:

active

WebUI 与 SetConfig 通道则无需重启。

9.3 改了钩子命令但不触发

三步排查:确认钩子挂在正确的计划/仓库上;确认 conditions 覆盖了实际发生的事件(实测教训:成功事件只匹配 CONDITION_SNAPSHOT_SUCCESS,失败走 CONDITION_ANY_ERROR);确认命令以服务用户可运行、输出路径可写(实测 /srv 根目录不可写导致 exit status 2)。

9.4 端口被占用导致启动失败

把服务单元 BACKREST_PORT 换一个空闲端口(如 9899)后:

systemctl restart backrest && systemctl is-active backrest

实测回显:

active
curl -s -o /dev/null -w "%{http_code}\n" http://127.0.0.1:9898/

实测回显:

200

(实测环境默认端口 9898 未被占用,服务正常监听;换端口后以同样的 curl 探测法验证新端口返回 200 即可。)

9.5 仓库密码忘记了怎么办

仓库密码只存在于 config.json(Backrest 托管)与 restic 仓库的 keys 目录中,无找回通道。立即从配置文件抄出 repos[].password 并存入密码管理器;若配置文件与密码一同丢失,仓库将永久无法解密——这是官方文档反复强调的第一优先级事项。

十、参考链接