> For AI agents: the site index is available at https://www.juniortree.com/llms.txt; this page is available as Markdown at https://www.juniortree.com/blog/server-backup.md.
> 分享服务器备份方案：Backrest+Rclone+OSS，遵循3-2-1原则确保数据安全

## Page metadata

- **Published:** 2025-05-18
- **Updated:** 2025-05-18
- **Tags:** 计算机
- **Source URL:** https://www.juniortree.com/blog/server-backup

# 服务器备份 - backrest + rclone + oss

主播虽然使用的基本是都是大厂的服务器，但是有时候因为自己手贱或者别的原因，经常导致服务崩溃，不得不重装系统

这时候备份就很有必要了，虽然之前尝试过使用基于 Duplicati 的服务器备份，但是这个工具我自己不是很喜欢（因为文件目录的关系），因此这次尝试另外一种方式

这次备份的架构将严格遵循 3-2-1 原则：
- 3：存储 3 份完整文件，一份原件加上两份拷贝。
- 2：将文件起码保持在两种不同的介质上。
- 1：将一份拷贝保存在异地。

云服务使用 [GitHub - garethgeorge/backrest: Backrest is a web UI and orchestrator for restic backup.](https://github.com/garethgeorge/backrest) 生成文件快照，然后使用 rclone 存储到香港地区的 OSS 上，此外再使用 [FreeFileSync: Open Source File Synchronization & Backup Software](https://freefilesync.org/) ，自动将其同步到本地的 Windows 电脑中，手动进行冷备份，那么我们现在就一步一步开始吧！

## Backrest 的安装与配置

Backrest 是 restic 的一个 GUI 版本，如果你对 CLI 情有独钟，也可以直接使用 restic

建议可以参考一下官方的文档，其中的一些基础概念对使用很有帮助：[Getting Started · Backrest](https://garethgeorge.github.io/backrest/introduction/getting-started)

Backrest 可以使用 Docker 进行安装：

```yml
services:
  backrest:
    image: garethgeorge/backrest:latest
    container_name: backrest
    hostname: backrest
    volumes:
      - ./backrest/data:/data
      - ./backrest/config:/config
      - ./backrest/cache:/cache
      - ./backrest/tmp:/tmp
      - /root/backup_targets:/userdata  # Mount local paths to backup
      - /root/easyImage:/easyImage
      - /root/minio:/minio
      - /root/gitea:/gitea
      - /root/opengist:/opengist
      - ./repos:/repos     # Mount local repos (optional for remote storage)
    environment:
      - BACKREST_DATA=/data
      - BACKREST_CONFIG=/config/config.json
      - XDG_CACHE_HOME=/cache
      - TMPDIR=/tmp
      - TZ=Asia/Shanghai
    ports:
      - "9898:9898"
    restart: unless-stopped
```

你需要把你要备份的目录映射到容器中，笔者尝试使用软链接连接到一个 `backup_targets` 文件夹中，但是由于软连接的特性，Backrest 好像只能识别到链接字符，并不能直接连接到内容，无法正常备份，我们只能使用这种比较恶心的方式了（不过如果是使用 restic 的话，默认应该是会跟随软连接的，我没有成功也不知道是为啥）

之后启动容器，配置好反向代理，刚进去的时候会让你进行设置，你需要设置好 Instance ID，如果在公网中，务必取消勾选 `Disable Authentication` ！并且设置好登录的用户名和强密码

![](https://s3.juniortree.com/pic/2025/05/69b0cedc375e70090bed55960bb7e31c.webp)

### 配置存储库

之后点击左边的 `Add Repo`，这里是保存备份数据的底层存储位置，也就是备份生成的快照会存在这里，虽然 Backrest 会为你保存好数据，但是当 Backrest 不可用的时候，你也可以直接使用 restic 直接对其进行底层操作

比较重要的有 `Repo Name`，也就是存储库的名字，`Repository URI`，也就是存储库的位置，这里的选择比较多，官方提供了好几种，在这里我只使用了前面 compose 挂载的本地，后面会使用 rclone 对本地挂载的同步到 oss 上，如果使用远程的存储方式，可能会比较耗时，国内的 ecs 带宽极小

![](https://s3.juniortree.com/pic/2025/05/9fbbbc507d35cca0b907d33283409a83.webp)

`Password` 也就是存储后快照的加密，如果你要使用的话，请务必保存好密码，一旦丢失将无法恢复

`Prune Policy` 中文名叫“修剪策略”，这个可能在 restic 的文档里面会更清楚一点：

![](https://s3.juniortree.com/pic/2025/05/1f3d0c37511136c7ed308cbbad51bacb.webp)

我在这里设置为每个月 1 号执行一次

`Check Policy` 备份完整性检查，这里的 `Read Data` 会按照固定的比例来选取需要检查的数据

我在这里设置比例为 `20%`，并且每周检查一次

![](https://s3.juniortree.com/pic/2025/05/9de85efa4825f7cf1fdcdddad3dc49bc.webp)

最下面有一个 `Preview`，可以对照我的来参考一下：

![](https://s3.juniortree.com/pic/2025/05/d87da076d095d46ad16fdd4b3231f916.webp)

### 配置备份计划

也是点击左边的 `Add Plan`，和前面一样输入 `Plan Name`，这里的 `Repository`，选择前面添加的 `Repo`

`Paths` 这里就需要添加前面 compose 你挂载的路径了

`Backup Schedule` 就是你需要配置的备份时间，我这里是每天晚上 12 和中午 12 点各备份一次

![](https://s3.juniortree.com/pic/2025/05/86e997bbccfc67bf8a8ea7d56348407a.webp)

这里的 `Retention Policy` 是我个人认为极有意思的地方，它提供了三种方式，这里的 `None` 就是手动触发，没意思我就不讲

`By Count` 就是按照最新的快照个数进行备份，比如说下面这个就是保存最新的 30 个快照

![](https://s3.juniortree.com/pic/2025/05/58f16d76b8228cbf419f8e7ed33e140c.webp)

`By Time Period` - 基于时间的保留策略，Gemini 的理解是这样的：

![](https://s3.juniortree.com/pic/2025/05/eed55e1d28f518ca416cc5a60cbd8ea6.webp)

传统的基于快照个数来保存可能会存在，比如说这 30 个都没啥变化，但我需要的是前面的时间备份，通过这种策略可以构建出灵活且符合需求的策略，例如保留近期的每日备份以便快速恢复，同时保留更长时间的历史备份以应对更久远的数据恢复需求

![](https://s3.juniortree.com/pic/2025/05/e09de953a8ef659aeb03c9ba1712e63e.webp)

同样我的 JSON 文件如下，可以供你参考：

![](https://s3.juniortree.com/pic/2025/05/b4b4039066fa5d858fd925cfe32e9763.webp)

然后可以手动点一下，看看能不能正常备份：

![](https://s3.juniortree.com/pic/2025/05/755e63c5b3cd21fc82233841dfc5d609.webp)
我这里还会有比较详细的计划

![](https://s3.juniortree.com/pic/2025/05/b0f603056f34d3487d915e30bb1bafeb.webp)

服务器的文件夹里面也会有对应的东西：

![](https://s3.juniortree.com/pic/2025/05/5371169fe240a608e9d7ebb2d456f62e.webp)

至此，Backrest 的配置就完成了

## Rclone 的配置

可以使用官方提供的一键脚本来进行安装：

```bash
curl https://rclone.org/install.sh | sudo bash
```

之后来配置 OSS

### OSS

阿里云的 OSS 加入了 Cloudflare 带宽联盟，出了中国大陆和迪拜地区，其他地方都提供了比较牛的额度

![](https://s3.juniortree.com/pic/2025/05/a7a1841e4afee775c52781c3812c8e68.webp)

虽然说这个是用来备份的，但是我觉得万一哪一天真得取回数据，这一点成本能省还是得省

所以我买的是中国香港地区的 OSS 的资源包，40 G，标准 - 本地冗余存储，一年 9.9

![](https://s3.juniortree.com/pic/2025/05/21c61328699007ccee30d4855af7e76f.webp)

至于这个同城冗余和本地冗余有啥区别，我还专门到问客服，简单来说就是同城冗余的可靠性要比本地冗余高一点，高多少呢？我们可以在文档中心看到：[OSS的存储冗余类型\_对象存储(OSS)-阿里云帮助中心](https://help.aliyun.com/zh/oss/user-guide/overview-of-storage-redundancy-types/?scm=20140722.H_2376655._.OR_help-T_cn%7Ezh-V_1)

![](https://s3.juniortree.com/pic/2025/05/74f99e43bcb8c9a094e34afbf17b3274.webp)

![](https://s3.juniortree.com/pic/2025/05/59726e5767cbdc3b6e3f72e40e7d9e36.webp)

差不多就是又多了一个 9，但是对我来说我觉得本地冗余存储的可靠性已经足够高了，同城冗余的价格要贵得多，对我来说并不划算，如果你有需求可以上

### 在 Rclone 上挂载 OSS

因为忘记截图了，所以具体细节你可以去百度或者 Google 一下，主要的难度是阿里云的这个权限控制颗粒度比较高，你得先新建一个 RAM 用户，然后再生成 AccessKey ID
和 Key，之后再给这个用户读和写 OSS 的权限

![](https://s3.juniortree.com/pic/2025/05/e37bf431518040f39ed3a96f9a6b1023.webp)

用多了 Cloudflare 这种可能不大习惯，但其实还挺方便的

之后创建一个新的桶，一定要把地域选为你资源包买的地域，而且存储冗余类型也要对应上！不然可能就用不了资源包了，直接扣费，并且确认是私有读，私有写，避免被刷，版本控制我没用过，用之前最好问问客服会不会产生额外费用

![](https://s3.juniortree.com/pic/2025/05/9be88435744231849e2f6271018c546e.webp)

之后可以在 rclone 中测试一下了：

```bash
rclone ls oss:<改为你的桶名>
```

### 上传备份文件

Rclone 提供了 `copy` 和 `sync` 两种方法，我只希望 OSS 和本地的完全一样，因为太多的快照可能导致 OSS 过大，产生额外费用

```bash
rclone sync <改为前面挂载的backrest的repo路径> oss:<改为你的桶名> -P
```

不出意外的话应该就可以上传了，这里会自动显示进度和速度

之后可以写一个定时任务，每天凌晨三点钟自动上传到 OSS 中

```bash
crontab -e
```

然后写入，每天凌晨三点自动同步

```bash
0 3 * * * rclone sync /backrest/repos oss:backrest >> /var/log/rclone-backup.log 2>&1
```

值得注意的是，使用 rclone 对文件进行上传属于 PUT 请求，每月 500 万次内不要钱，超过部分 0.01 元/万次：[定价详情](https://www.aliyun.com/price/detail?scm=20140722.M_10513479._.V_1&saleProductCode=oss)

![](https://s3.juniortree.com/pic/2025/05/9eb51a8e529629affdcb05873136fbcc.webp)

上传完了记得去看看资源包有没有生效，以免产生别的额外费用，一般会有延时，1-3 个小时

![](https://s3.juniortree.com/pic/2025/05/e72bb2f9700926d3979e2e4bcee1cd46.webp)

## 使用 Rsync 和 FreeFileSync 进行同步

我原本想的是直接从国内的 ECS 用 FreeFileSync 拉到本地的电脑上，然后定期存到另外的硬盘做冷备份的，但是国内 ECS 的带宽实在是太小太小了，如果在同步的过程中有用户访问的话会影响体验

所以我先使用 Rsync 将国内的 ECS 的备份仓库同步到国外的大带宽的 VPS 上，之后再使用 FreeFileSync 自动同步到 Windows 上

```bash
rsync -avz -e ssh /root/backrest/repos root@xx.xxx.xx.xxr:/home/beijing
```

需要注意的是 Rsync 的同步是单向的

## Syncthing 配置（可选）

笔者在日本区域还有台服务器，帮朋友托管了一个 Memos，我也希望能能将这个也通过上述方式，存入到可靠的服务中

这时候就可以使用 Syncthing 来在两台 VPS 中进行同步

```bash
services:
  syncthing:
    image: syncthing/syncthing
    container_name: syncthing
    hostname: my-syncthing
    environment:
      - PUID=1000
      - PGID=1000
    volumes:
      - ./st-sync:/var/syncthing
      - /root/memos:/memos:ro
    network_mode: host
    restart: unless-stopped
    healthcheck:
      test: curl -fkLsS -m 2 127.0.0.1:8384/rest/noauth/health | grep -o --color=never OK || exit 1
      interval: 1m
      timeout: 10s
      retries: 3
```

这里对其目录进行挂载，并且设置为只读

需要放行以下端口：

![](https://s3.juniortree.com/pic/2025/05/a8430b1556ad6a62d54606e6e6b56a56.webp)

以 `PUID=1000` 和 `PGID=1000` 运行容器有一个坑，就是容易出现权限不够的情况，这里设置为只读，文件夹类型设置为仅发送，即可正常使用

![](https://s3.juniortree.com/pic/2025/05/64442a460188e9fd2fb594d52668f51c.webp)

同时需要配置另外一台服务器，然后进行配对即可

## 总结

目前这样就基本满足我的备份要求了，希望我做这些都是多余的，数据永远都不会丢！
