使用 rclone 来实时备份网站服务器数据

拥抱rclone

在试用了一段时间的mega之后,发现几个缺陷:一是如果在备份过程中文件被修改了,mega会忽略这些文件,造成备份数据丢失,目前没有找到相关的参数;二是通过账号密码登陆,这里面存在安全隐患;三是mega的存储空间计算是算上了历史版本的,这样的话,50G容量就不太够用了。虽然可以通过每次备份来完成类似的效果,不过还是倾向于实时备份,这样的话还能启动另外一个VPS来做热备份。

一通寻找之下发现了rclone,rclone不是一个存储服务,而是整合了很多的存储平台,然后提供统一的接口,能提供更加复杂的备份逻辑,而且也不与任何实际的存储服务相耦合,便于在各个平台之间迁移,也算是一个神器了吧。

在容器中运行rclone

首先创建一个目录用于存放rclone数据,免得容器挂了之后还要重新配置

1
sudo mkdir -p /home/rclone

启动rclone容器

1
2
3
4
5
6
7
8
9
docker run \
--name rclone \
-d \
--restart always \
--cpus 0.2 \
--mount type=bind,src=/etc/localtime,dst=/etc/localtime,readonly \
--mount type=bind,src=/data/,dst=/data,readonly \
--mount type=bind,src=/home/rclone/,dst=/root/ \
newnius/rclone

假设你的VPS数据目录是/data
尽管rclone的sync是单向的,但是为了数据安全性,还是选择让容器只读

配置远程存储

1
docker exec -it rclone rclone config

输入n来新增一个远程存储;
给新存储指定一个名字,名字随意,为了方便区分,这里输入dropbox
选择远程存储类型,输入8选择Dropbox,随着rclone不断升级,这里的序号可能会变;
id 和 secret 留空,高级设置选n,自动配置选y
会看到请在浏览器中访问页面的提示;

rclone 配置

rclone 配置

因为VPS是没有桌面的,而且docker容器中就更不可能有桌面了,官方推荐是在另外的机器上(自己的电脑啥的)生成授权码,不过我感觉这样太麻烦了,除了本机要装rclone之外,还需要本地中端能访问dropbox,国内这烂环境,而且mac下也很难配置全局代理,所以换了一种方式。

根据OAuth2协议,客户端生成一个跳转链接,在目标站点完成授权后再次跳转到回调链接即可。根据这个特点。我们只要拿到这两个链接,然后授权这一步在本地浏览器上做就行,浏览器设置代理就太容易了。

首先获取客户端跳转链接,在VPS上打开另一个终端

1
docker exec -it rclone curl http://127.0.0.1:53682/auth

获取跳转链接

会看到返回了一串html代码,把href参数中的链接复制出来(也就是双引号中间的部分),这个链接被编码过了,直接访问会解析参数错误,所以需要先解码,这里使用了站长工具的UrlDecode。把链接复制进去,然后点击解码,再把结果链接复制,然后浏览器打开,选择accept。

然后会跳转到一个新的页面,浏览器提示链接拒绝,复制地址栏的链接,在VPS上终端下访问,完成OAuth2授权(服务器需要能够直连dropbox)

1
docker exec -it rclone curl "http://localhost:53682/?state=xxxxx"

把地址换成你自己的
双引号是必须的,否则在shell下会解析错误

获取跳转链接

不出意外,就能看到 All done. Please go back to rclone 输出了。

回到刚刚的终端下,会看到已经授权成功,然后选择y一切正常,再输入q退出配置。

完成授权登陆

至此,rclone的配置和授权就完成了,接下来要配置一下同步/备份策略。

设置备份策略

因为每个人的备份策略不一样,所以镜像中没有默认开启备份,需要自己编写

在启动容器时,会自动复制一个默认的备份脚本到 /home/rclone/sync.sh,这个脚本什么也不干。

首先要修改权限,否则普通用户无法修改。

1
sudo chmod 777 /home/rclone/sync.sh

根据你自己的需求,修改 /home/rclone/sync.sh文件

1
2
3
4
5
6
7
while true; do

rclone sync /data/ dropbox:/ --local-no-check-updated --ignore-size --ignore-checksum

sleep 300

done

由于rclone的sync目前仍不支持后台进程,从而自动同步修改的文件,所以需要自己在文件变动后再次执行sync,所以我是把同步任务放到了无限循环里,rclone在同步时会自动忽略相同的文件。

根据数据的不同,如果是数据库文件的话,变化频繁而且文件内容大,实时备份会消耗占用较大的流量。可以设置一定的备份间隔,减少流量消耗。

由于是热备份,在备份过程中文件可能会被修改,为了保持一致性,rclone会拒绝同步该部分文件,可以通过添加后面的三个参数来忽略这些错误,继续备份这些文件。

修改完毕之后,重启容器,开始执行备份任务

1
docker restart rclone

可以在dropbox网页端看到文件已经在同步了。

同步中

参考

Dropbox | rclone

Configure | rclone

ncw/rclone

Feature request: Listen filesystem events and sync

Possibility to ignore size and checksum when copying to avoid errors - –ignore-checksum flag

Failed to copy: can’t copy - source file is being updated (mod time changed

corrupted on transfer: sizes differ

rclone Keeps Failing to Copy File with “corrupted on transfer”