自动备份服务器数据到 NextCloud
2024-02-28 更新:使用 zstd 压缩(
.tar.gz
->.tar.zst
;tar czvf
->tar cavf
)
突发奇想:在 NextCloud 创建一个 File drop 分享,然后写一个打包上传脚本,就可以把它当备份服务器用啦。
功能/特点:
- 分别备份多个源目录到 tar 文件并上传到 NextCloud share;
- 每周上传完整备份,每天上传增量备份(利用 tar 增量备份);
- 只需要 NextCloud 的 File drop 链接,由于 File drop 只能用于上传,禁止列出/下载文件,脚本泄露不会造成其它数据的泄露。
脚本
需要根据分享链接修改 BASEURL
、SHARETOKEN
两个变量,代码中以 https://example.com/s/AAAAAAA
为例。
以及需要修改 dobackups()
函数,可以调用多次 backup NAME PATH
,每次调用会将 PATH
路径打包为 NAME_***.tar.zst
并上传到 File drop。
#!/bin/bash
### BEGIN OF USER CONFIG
BASEURL="https://example.com"
SHARETOKEN="AAAAAAA"
BASE_LISTPATH="/var/lib/backup"
BASE_TMPPATH="/tmp"
FULL_BACKUP_DAY="1" # 1 = Monday; 7 = Sunday
dobackups() {
backup YOUR_DATA_NAME_1 /PATH/TO/YOUR_DATA1
backup YOUR_DATA_NAME_2 /PATH/TO/YOUR_DATA2
}
### END OF USER CONFIG
mkdir -p "$BASE_LISTPATH" "$BASE_TMPPATH"
declare -a success=()
declare -a failed=()
backup() {
local label="$1"
local listpath="$BASE_LISTPATH/${label}.snar"
local dirpath="$2"
echo "==> Creating backup '$label' from $dirpath"
if [[ $(date +%u) == $FULL_BACKUP_DAY ]]; then
rm "$listpath"
fi
[[ -f "$listpath" ]] ; full=$?
local packname="${label}_$(date +%Y%m%d_%H%M%S)_$([[ $full == "1" ]] && echo "full" || echo "incremental").tar.zst"
local packpath="$BASE_TMPPATH/$packname"
echo "==> tar file path '$packpath'"
local filecount=$(tar cavf "$packpath" -g "$listpath" "$dirpath" | wc -l)
echo $filecount files packed
if [[ $filecount == "0" ]] && [[ $full == "1" ]] ; then
failed+=("$label")
return 1
fi
echo "==> Uploading $packpath"
curl -T "$packpath" -u "$SHARETOKEN:" -H 'X-Requested-With: XMLHttpRequest' "$BASEURL/public.php/webdav/$packname" && success+=("$label") || failed+=("$label")
echo "==> Delete $packpath"
rm "$packpath"
}
dobackups
echo SUCEESS: ${success[@]}
if [[ ${#failed[@]} -gt 0 ]]; then
echo FAILED: ${failed[@]}
exit 1
fi
Systemd 配置
为了让脚本定时启动,给 systemd 增加一个 service 和一个 timer。
文件 /etc/systemd/system/simplebackup.service
:
[Unit]
Wants=simplebackup.timer
[Service]
Type=simple
ExecStart=/etc/backup.sh
[Install]
(假设脚本位于 /etc/backup.sh
)
文件 /etc/systemd/system/simplebackup.timer
:
[Unit]
Requires=simplebackup.service
[Timer]
Unit=mybackup.service
OnCalendar=*-*-* 3:00:00
[Install]
WantedBy=timers.target
(每天凌晨 3 时运行)
启用 timer:
sudo systemctl enable --now simplebackup.timer
作为测试,手动运行一次 service:
sudo systemctl start simplebackup.service