Backrest v1.14.1 常用 CLI 命令详解

Backrest 视角的命令行运维手册:主程序参数、systemd 管理、托管 restic 命令矩阵(snapshots/ls/stats/check/unlock/restore)、原生命令接口与日志排障,全程实测。

Backrest命令行备份恢复Restic2026/10/26

Backrest v1.14.1 常用 CLI 命令详解

目标:以 Backrest 视角梳理日常运维所需的全部命令行入口——backrest 主程序参数、systemd 服务管理、托管 restic 命令矩阵、Backrest 原生命令接口与日志排障。本文全部命令与回显已在 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(托管路径 /home/admin/.local/share/backrest/restic);
  • 仓库:local-demo(URI /srv/backups/local-demo,仓库口令 q1w2e3r4);
  • 计划:demo-docs(备份 /srv/demo-data,cron */5 * * * *,保留最近 3 份);
  • 服务用户:admin;API 入口:http://127.0.0.1:9898。

二、工具概览

Backrest 的命令行运维入口共四类,分工如下:

入口命令用途
主程序backrest启动服务本身(由 systemd 调用),附 -version/--help 等参数
托管 restic/home/admin/.local/share/backrest/restic直接操作仓库:快照/统计/检查/解锁/恢复
安装脚本install.sh / uninstall.sh安装、重装(升级)、卸载
服务与日志systemctl / journalctl服务生命周期管理与日志排查

💡 说明:Backrest 对外提供的 gRPC 接口(WebUI 同款)也是命令行可用的运维入口(curl 调用),适合脚本化;本文第七节给出实测示例。六、7.x 节编号从简,以实际标题为准。

三、前置条件

  • 服务处于运行态:
systemctl is-active backrest

实测回显:

active
  • 知道仓库口令(Backrest 托管模式下口令存于 config.json,直接调用 restic 时必须显式提供环境变量 RESTIC_PASSWORD):
grep -o '"password": "[^"]*"' /home/admin/.config/backrest/config.json

实测回显:

"password": "q1w2e3r4",
  • 建议为 restic 指定独立缓存目录,避免与 Backrest 托管缓存混写(示例统一用 /tmp/restic-cache)。

四、backrest 主程序命令行参数

4.1 版本查看

/usr/local/bin/backrest -version

实测回显:

If you're reading this, you're unnecessarily importing github.com/ncruces/go-sqlite3/embed.
backrest version: 1.14.1, commit: 875c9cb51e626a75276a64da42c6a9ec0695010a

💡 说明:第一行是上游 sqlite 构建库的提示输出,每个版本都会带,属正常现象;版本核对只看第二行。

4.2 全部启动参数

/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

命令格式速查:

命令作用等价环境变量
backrest -bind-address 0.0.0.0:9898改监听地址与端口BACKREST_PORT
backrest -config-file /etc/backrest/config.json改配置文件路径BACKREST_CONFIG
backrest -data-dir /var/lib/backrest改数据目录BACKREST_DATA_DIR
backrest -restic-cmd /usr/local/bin/restic改用自备 resticBACKREST_RESTIC_COMMAND
backrest -install-deps-only只安装托管依赖(restic)后退出—
backrest -version打印版本退出—

⚠️ 注意:日常运维不要手跑 backrest 主进程(会与 systemd 托管实例抢配置、抢端口);改启动参数的正确位置是 systemd 单元或其环境变量,改完 systemctl restart backrest。

五、systemd 服务管理

5.1 状态与自启

systemctl status backrest --no-pager -l | head -7

实测回显:

● backrest.service - Backrest Service
     Loaded: loaded (/etc/systemd/system/backrest.service; enabled; vendor preset: enabled)
     Active: active (running) since Mon 2026-10-26 08:25:56 UTC; 8min ago
   Main PID: 3748 (backrest)
      Tasks: 12 (limit: 3172)
     Memory: 14.0M
        CPU: 18.861s
systemctl is-enabled backrest

实测回显:

enabled

5.2 重启与停启

systemctl restart backrest && systemctl is-active backrest

实测回显:

active
systemctl stop backrest && systemctl is-active backrest

实测回显:

inactive

5.3 自启开关

systemctl disable backrest

实测回显:

Removed /etc/systemd/system/multi-user.target.wants/backrest.service.
systemctl enable backrest

实测回显:

Created symlink /etc/systemd/system/multi-user.target.wants/backrest.service → /etc/systemd/system/backrest.service.

六、restic 命令矩阵(Backrest 视角)

6.1 调用约定

Backrest 的仓库就是标准 restic 仓库,CLI 直连的三要素如下(缺一不可):

export RESTIC_PASSWORD=q1w2e3r4
R=/home/admin/.local/share/backrest/restic
RC="--cache-dir /tmp/restic-cache"
$R version

实测回显:

restic 0.19.1 compiled with go1.26.4 on linux/amd64

命令格式速查(本节全部实测):

命令作用关键点
$R -r /srv/backups/local-demo $RC snapshots快照列表需 RESTIC_PASSWORD
$R … snapshots --jsonJSON 形式快照列表便于脚本解析
$R … ls latest浏览最新快照文件树latest 也可换成快照 ID
$R … stats --mode raw-data仓库容量统计raw-data 模式统计压缩后真实占用
$R … check仓库完整性检查输出 no errors were found 即健康
$R … unlock清理残留锁无输出、退出码 0
$R … restore <id> --target <dir> --path <snap内路径>恢复目标目录需不存在、父目录可写

⚠️ 注意:-r 指定仓库路径、$RC 指定独立缓存目录、RESTIC_PASSWORD 提供仓库口令——Backrest 界面操作由其自动注入这三样,手跑 CLI 则要自己带全。

6.2 快照类:snapshots 与 ls

$R -r /srv/backups/local-demo $RC snapshots

实测回显:

ID        Time                 Host             Tags                                        Path
--------------------------------------------------------------------------------------------------------
c73363b1  2026-10-26 08:27:06  backrest-server  plan:demo-docs,created-by:backrest-server   /srv/demo-data
3f0eb479  2026-10-26 08:28:24  backrest-server  plan:demo-docs,created-by:backrest-server   /srv/demo-data
87e1d55e  2026-10-26 08:30:01  backrest-server  plan:demo-docs,created-by:backrest-server   /srv/demo-data
--------------------------------------------------------------------------------------------------------
3 snapshots

JSON 形式(便于取精确快照 ID):

$R -r /srv/backups/local-demo $RC snapshots --json | python3 -c "import sys,json; [print(s['id'][:12], s['time'], s['tags']) for s in json.load(sys.stdin)]"

实测回显:

c73363b1d43c 2026-10-26T08:27:06.653044052Z ['plan:demo-docs', 'created-by:backrest-server']
3f0eb479d42f 2026-10-26T08:28:24.610471834Z ['plan:demo-docs', 'created-by:backrest-server']
87e1d55ed0b7 2026-10-26T08:30:01.494210209Z ['plan:demo-docs', 'created-by:backrest-server']

浏览最新快照的文件树:

$R -r /srv/backups/local-demo $RC ls latest

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

snapshot 19fed39f of [/srv/demo-data] at 2026-10-26 08:45:01):
/srv/demo-data
/srv/demo-data/file1.txt
...

💡 说明:latest 指向 cron 08:45 新产生的快照——保留策略 policyKeepLastN: 3 已把 08:27/08:28 的旧快照裁掉,这正是 Backrest 编排 forget 的痕迹;plan:/created-by: 标签是 Backrest 归属快照与执行保留策略的依据。

6.3 统计类:stats

$R -r /srv/backups/local-demo $RC stats --mode raw-data

实测回显:

Stats in raw-data mode:
Total Blob Count:   16
Total Uncompressed Size: 66.743 KiB
Total Compressed Size: 65.380 KiB
Compression Ratio: 1.02x
Compression Savings: 2.04%
Total Size: 65.380 KiB

6.4 健康类:check 与 unlock

$R -r /srv/backups/local-demo $RC check

实测回显:

create exclusive lock for repository
load indexes
check all packs
check snapshots, trees and blobs
no errors were found
$R -r /srv/backups/local-demo $RC unlock

实测回显(命令无输出,退出码 0):

⚠️ 注意:check 需要排他锁,服务端正在备份时执行会等待或报锁冲突;Backrest 自身的 check 任务入口见七、7.3,由编排器调度的 check 不需要手工加锁。

6.5 恢复类:restore

$R -r /srv/backups/local-demo $RC restore c73363b1d43cf444f8888429f65d268ee3740b0eae8628c0a37bea85123ad232 --target /srv/backups/restore-cli --path /srv/demo-data

实测回显(当时该快照已被保留策略裁掉):

Load(<snapshot/c73363b1d4>, 0, 0) failed: open /srv/backups/local-demo/snapshots/c73363b1d43cf444f8888429f65d268ee3740b0eae8628c0a37bea85123ad232: no such file or directory
Fatal: failed to find snapshot: failed to load snapshot c73363b1: open /srv/backups/local-demo/snapshots/c73363b1d43cf444f8888429f65d268ee3740b0eae8628c0a37bea85123ad232: no such file or directory

改用现存快照(从 snapshots --json 取 ID):

SID=$($R -r /srv/backups/local-demo $RC snapshots --json | python3 -c "import sys,json;print(json.load(sys.stdin)[-1]['id'])")
$R -r /srv/backups/local-demo $RC restore $SID --target /srv/backups/restore-cli --path /srv/demo-data

实测回显:

Summary: Restored 6 files/dirs (64.062 KiB) in 0:00

验证内容一致:

md5sum /srv/demo-data/random.bin $(find /srv/backups/restore-cli -name random.bin)

实测回显:

edeb9c386e69c13092515c3955b5e55f  /srv/demo-data/random.bin
edeb9c386e69c13092515c3955b5e55f  /srv/backups/restore-cli/srv/demo-data/random.bin

💡 说明:两种恢复入口的落盘语义不同——CLI restore --path /srv/demo-data 会在目标下保留完整相对路径(target/srv/demo-data/…);Backrest 的 Restore 接口/WebUI 则以快照内路径为根(target/demo-data/…)。写自动化脚本时以实测落盘路径为准。

七、Backrest 原生命令入口(接口方式)

7.1 立即备份

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"}' -w "\n[%{http_code}]\n"

实测回显:

{}
[200]

⚠️ 注意:请求体是计划 ID 而非 JSON 对象包裹;Content-Type 必须是 application/json 且带 Connect-Protocol-Version: 1 头,缺失该头时请求会按二进制协议解析并报 decode …: illegal base64 data 类错误(实测踩坑结论)。

7.2 操作记录查询

curl -s -X POST http://127.0.0.1:9898/v1.Backrest/GetOperations \
  -H "Content-Type: application/json" -H "Connect-Protocol-Version: 1" \
  -d '{"selector":{"planId":"demo-docs"},"lastN":3}' | python3 -m json.tool | head -30

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

{
    "operations": [
        {
            "id": "2",
            "status": "STATUS_SUCCESS",
            "operationBackup": {...},
            "displayMessage": "backup for plan \"demo-docs\"",
            ...

7.3 仓库维护任务

curl -s -X POST http://127.0.0.1:9898/v1.Backrest/DoRepoTask \
  -H "Content-Type: application/json" -H "Connect-Protocol-Version: 1" \
  -d '{"repoId":"local-demo","task":"TASK_CHECK"}' -w "\n[%{http_code}]\n"

实测回显:

{"operationId":"22"}
[200]

task 可选值:TASK_INDEX_SNAPSHOTS(索引快照)、TASK_PRUNE(清理未引用数据)、TASK_CHECK(完整性检查)、TASK_STATS(统计)、TASK_UNLOCK(解锁)。任务在编排器队列中异步执行,结果用 7.2 的 GetOperations 查询(实测两个任务均 STATUS_SUCCESS)。

7.4 在仓库上跑自定义 restic 命令

curl -s -X POST http://127.0.0.1:9898/v1.Backrest/RunCommand \
  -H "Content-Type: application/json" -H "Connect-Protocol-Version: 1" \
  -d '{"repoId":"local-demo","command":"snapshots --compact"}' -w "\n[%{http_code}]\n"

实测回显:

{"operationId":"37"}
[200]

该接口即 WebUI 仓库页「Run Command」的等价调用,输出写入操作日志(GetOperations 查询,实测 STATUS_SUCCESS)。适合临时跑 restic 子命令而不想自带口令的场景。

八、日志与排障

8.1 三个日志位置

日志路径/命令内容
进程日志/home/admin/.local/share/backrest/processlogs/backrest.log启动、restic 安装、监听端口
systemd 日志journalctl -u backrest调度、任务执行、错误
操作日志GetOperations / WebUI 操作页每次备份/forget/prune/check 的结构化记录

进程日志开头三行(实测 head -3):

{"level":"info","ts":1793002345.615185,"caller":"cmd/backrest.go:71","msg":"installing restic if missing…"}
{"level":"info","ts":1793002357.749832,"caller":"resticinstaller/resticinstaller.go:290","msg":"Successfully validated restic"},{"path":"/home/admin/.local/share/backrest/restic"}
{"level":"info","ts":1793002357.7501943,"caller":"api/server.go:153","msg":"http server listening on 0.0.0.0:9898"}

8.2 常用 journalctl 过滤命令

journalctl -u backrest --no-pager | grep -E "running task" | tail -2

实测回显:

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"}
journalctl -u backrest --no-pager | grep -E "failed|error" | tail -2

实测回显(排障期真实记录,GitHub 不可达导致 restic 自动安装失败):

Oct 26 08:21:33 backrest-server backrest[1006]: {"level":"error","ts":1793002893.0953624,"caller":"resticinstaller/resticinstaller.go:120","msg":"failed to download restic","error":"Get \"https://github.com/restic/restic/releases/download/v0.19.1/restic_0.19.1_linux_amd64.bz2\": dial tcp 20.205.243.166:443: connect: connection refused"}

8.3 典型故障速查

现象定位命令结论与处置
服务反复重启`journalctl -u backrestgrep install.lock`
备份成功但钩子失败`journalctl -u backrestgrep "exit status"`
恢复报 target exists接口响应原文目标目录须不存在且父目录对服务用户可写(实测回显见部署篇十、10.4)
CLI 恢复报 failed to find snapshot$R … snapshots --json该快照已被保留策略 forget,改用现存快照 ID(实测回显见六、6.5)
接口调用报 illegal base64响应 code 字段补 Connect-Protocol-Version: 1 头(实测结论见七、7.1 注意)

九、注意事项

  • 口令管理:仓库口令由 Backrest 托管在 config.json;CLI 直连需自备 RESTIC_PASSWORD,两处口令必须一致,轮换时同步修改;
  • 缓存目录:CLI 建议用独立 --cache-dir,与 Backrest 托管缓存隔离,避免锁冲突;
  • 锁语义:restic 仓库同一时刻只允许一个写者;服务端任务运行期间手跑 check(排他锁)可能等待或冲突,读类命令(snapshots/ls/stats)无此问题;
  • 标签体系:Backrest 依赖 plan:/created-by: 标签做归属与保留策略,手动 restic backup 产生的快照不带这些标签,会游离于计划体系之外(可在界面用索引快照功能纳入管理),日常备份请走计划调度;
  • 幂等运维:install.sh 可重复执行(重装即升级),卸载用包内 uninstall.sh(完整流程见部署篇十一)。

十、常见问题(FAQ)

10.1 restic CLI 报「Fatal: wrong password or no key found」

环境变量 RESTIC_PASSWORD 与仓库实际口令不一致。核对 config.json 中 repos[].password(见三、前置条件的 grep 实测)后重试。

10.2 服务端口想换,改哪里最稳

改 systemd 单元的 Environment="BACKREST_PORT=0.0.0.0:<端口>"(与 install.sh 写法一致)后重启;验证用 curl -s -o /dev/null -w "%{http_code}\n" http://127.0.0.1:<端口>/ 返回 200。

10.3 想在不暴露口令的前提下跑 restic 子命令

用七、7.4 的 RunCommand 接口或 WebUI 的 Run Command 入口,由 Backrest 注入口令与路径执行,输出进操作日志可审计。

10.4 如何确认计划真的在按时跑

journalctl -u backrest --no-pager | grep -E "scheduled task|running task" | tail -4

实测回显(调度与执行成对出现):

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"}

十一、参考链接