前言
Halo的备份功能是需要手动点击的,而自动备份插件是收费的,用脚本自动备份可以省49.9元
根据这篇文章 利用aligo实现Halo自动备份数据到阿里云盘 的方法,修改了一下,我不用阿里云盘,我使用rclone上传到远端
检查/安装Python环境
先看看当前环境有没有安装Python环境,我的VPS是已经预装了的
Debian系基本都预装了Python3,CentOS预装的是Python2(不知道可不可以用)
python3 --version
没有的就自行安装一下,会自动处理依赖装上python3
apt install python3-pip
安装脚本相关Python依赖
还需要安装python3 和脚本中代码 import requests
写的这些相关的依赖,如requests等,我不懂python, pip3 install requests
提示这个,问GPT他说是外部环境,让我用 apt install python3-requests
,然后他显示我已经安装过了,可能我的VPS自带了这个环境和这些依赖吧,不用安装其他依赖了。
没有的就自己安装一下,不止requests还有json等,但可能自带了的
apt install python3-requests
或者
pip3 install requests
或者
pip install requests
编写备份脚本
nano /root/backup-halo.py
,新建个脚本,粘贴以下内容,登录信息、Halo的backups文件夹所在位置等相关信息需要修改
import base64
import time
import requests
import json
import shutil
from datetime import datetime, timedelta
# from aligo import Aligo
# Halo的网站地址,本机可填 127.0.0.1
website = "http://127.0.0.1:8090"
# Halo的管理员登录信息
user = "HaloAdminUser"
password = "YourPassword"
# halo2.x的备份文件夹路径,在Halo项目文件夹里的
backup_halo_path = "/docker/halo/data/backups"
# 备份要拷贝到的目录,我rclone挂载到本地,所以上传这样做
# 需要确保该目录存在 自行创建如mkdir -p /mnt/rclone/backup
target_directory = "/mnt/rclone/backup"
# 调用的API相关
backup_api = website + "/apis/migration.halo.run/v1alpha1/backups"
check_api = website + "/apis/migration.halo.run/v1alpha1/backups?sort=metadata.creationTimestamp%2Cdesc"
# 获取现在的时间 形如 2023-09-24T13:14:18.650Z
# 备份文件在halo后台保留的时间,我设置3天
now_time = datetime.now().strftime('%Y-%m-%dT%H:%M:%S.%f')[:-3] + 'Z'
now_datetime = datetime.fromisoformat(now_time.replace('Z', '+00:00'))
delay_days = timedelta(days=3)
delay_days_later = now_datetime + delay_days
expires_time = delay_days_later.strftime('%Y-%m-%dT%H:%M:%S.%f')[:-3] + 'Z'
print(f"脚本运行日期:{now_time}")
# 构建认证头部
auth_header = "Basic " + base64.b64encode((user + ":" + password).encode()).decode()
payload = json.dumps({
"apiVersion": "migration.halo.run/v1alpha1",
"kind": "Backup",
"metadata": {
"generateName": "backup-",
"name": ""
},
"spec": {
"expiresAt": expires_time,
}
})
headers = {
'User-Agent': '',
'Content-Type': 'application/json',
'Authorization': "Basic " + base64.b64encode((user + ":" + password).encode()).decode(),
}
response = requests.request("POST", backup_api, headers=headers, data=payload)
# 输出请求响应的信息文本
# print(response.text)
print(f"响应文本:{response.text}")
# 检查响应的代码,执行操作
if response.status_code == 201:
print("备份请求成功!")
new_backup_name = ""
while True:
check_response = requests.request("GET", check_api, headers=headers)
if check_response.status_code == 200:
backup_data = json.loads(check_response.text)
items = backup_data.get("items", [])
if items[0]["status"]["phase"] == "SUCCEEDED":
new_backup_name = items[0]["status"]["filename"]
print(f"备份完成!文件名:{new_backup_name}")
break
if items[0]["status"]["phase"] == "RUNNING":
print("正在备份,请稍等!")
# 处理中,3秒后再检查
time.sleep(3)
else:
print(f"查询备份请求失败!错误代码:{check_response.status_code}")
# 直接使用字符串拼接构建文件路径
source_file_path = backup_halo_path + "/" + new_backup_name
target_file_path = target_directory + "/" + new_backup_name
# 拷贝文件到目标目录
shutil.copy2(source_file_path, target_file_path)
# 输出成功消息
print(f"拷贝完成!已拷贝至:{target_file_path}")
else:
print(f"备份请求失败!错误代码:{response.status_code}")
# 添加换行,让每一次执行的日志隔开好看些
print(" ")
print(" ")
创建相关目录 mkdir -p /mnt/rclone/backup
,我是因为rclone挂载对象存储到本地的,所以已经有了,rclone挂载网盘到本地的方法本文不做讨论,自行搜索
你也可以使用其他的远端存储,比如alist、网盘,SMB、WebDav、另一个磁盘等,备份到本机自身存储的话,那系统崩了备份可能直接陪葬
尝试手动执行脚本
命令
python3 backup-halo.py
可以到halo后台看到这个备份的,API生成的备份包有效期是8小时,手动生成的有效期是7天,不知道怎么更改
已经添加了过期时间的设置,我设置为3天
定时调用该脚本
crontab里建议使用绝对路径,查询python3的绝对路径
which python3
#结果
/usr/bin/python3
crontab -e
,写入以下内容添加定时执行任务,
30 4,17 * * * /usr/bin/python3 /root/backup-halo.py >> /root/backup-halo.log 2>&1
- 如果没有crontab命令就自己安装一下
apt install cron
- crontab的定时规则自行查询
- 30 4,17 * * * 表示每天的凌晨4点30分,17点30分,执行后面的定时任务
- Python、脚本、日志的路径写绝对路径
- 2>&1 表示把错误信息也写到日志文件,因为>>只是把一般输出写到日志文件,而错误信息还是是输出到控制台的,我们是定时执行看不到控制台,所以要加这个参数
备份包备份了哪些数据
该zip备份包是完整的备份包,包括了用户信息、设置、文章、附件、插件、主题、及插件主题的数据等,包括了全部数据,恢复后和原来的一模一样
恢复方法
下载备份,然后Halo后台--备份--恢复--上传--选择文件--恢复
如果是迁移,需要全新安装Halo,然后到后台恢复。所以建议自行保存docker-compose.yml文件,方便重建
建议账户信息和之前的一样,否则会出现2个用户,文章都是原先的用户发的,不是刚创建的用户发的
参考信息: