127 lines
6.8 KiB
Bash
127 lines
6.8 KiB
Bash
#!/usr/bin/env bash
|
||
# =============================================================================
|
||
# Meta : Firefly III 备份执行脚本
|
||
# Version : 1.0.0
|
||
# Author : Bash Shell Senior Development Engineer
|
||
# License : MIT
|
||
# Description : 自动化执行 Firefly III 远程备份、同步、加密、上传及清理任务。
|
||
#
|
||
# 本脚本基于公司备份中心的通用框架,使用 common.sh 中定义的日志、远程执行、
|
||
# 加密与 rclone 函数实现。它假定 Firefly III 运行在名为 p3 的远程服务器
|
||
# 上,并且容器使用 MariaDB 作为数据库。由于 p3 的磁盘 I/O 性能较差,
|
||
# Firefly III 使用挂载在 /mnt/ramdisk 的 RAM 磁盘保存数据库和上传目录。
|
||
# 为保证数据持久性,本脚本会定期将数据拉取到备份中心并上传到异地存储。
|
||
# =============================================================================
|
||
|
||
set -euo pipefail
|
||
IFS=$'\n\t'
|
||
|
||
# -----------------------------------------------------------------------------
|
||
# 引入公共库
|
||
# -----------------------------------------------------------------------------
|
||
source "$(dirname "$0")/common.sh" || { echo "FATAL: common.sh not found." >&2; exit 1; }
|
||
|
||
# -----------------------------------------------------------------------------
|
||
# 配置区
|
||
# -----------------------------------------------------------------------------
|
||
readonly APP_NAME="FireflyIII"
|
||
readonly REMOTE_USER="root"
|
||
readonly REMOTE_HOST="p3"
|
||
# 远程主机的 SSH 端口继承自 common.sh 中的 REMOTE_SSH_PORT
|
||
readonly MAX_ENCRYPTED_REPLICAS=3 # 可根据需求调整远程保留的最大加密副本数
|
||
|
||
# MariaDB 容器名称及数据库凭据。建议通过环境变量传入,避免明文密码。
|
||
readonly REMOTE_DB_CONTAINER="firefly_iii_db"
|
||
# 从环境变量中读取数据库名称和凭据,默认值仅供示例使用。
|
||
readonly DB_USER="${FIREFLY_DB_USER:-firefly}" # 数据库用户名
|
||
readonly DB_PASSWORD="${FIREFLY_DB_PASSWORD:-ChangeThisPassword}" # 数据库密码
|
||
readonly DB_NAME="${FIREFLY_DB_NAME:-firefly}" # 数据库名
|
||
|
||
# 远程路径:FireflyIII 在 p3 上的 RAM 磁盘挂载目录。
|
||
readonly REMOTE_UPLOAD_DIR="/mnt/ramdisk/firefly_iii_upload"
|
||
readonly REMOTE_DB_RAMDIR="/mnt/ramdisk/firefly_iii_db"
|
||
|
||
# 本地备份目录。根据备份中心目录结构自定义,用于暂存同步文件。
|
||
readonly LOCAL_BACKUP_DIR="/data/p3_firefly_iii"
|
||
|
||
# -----------------------------------------------------------------------------
|
||
# 主执行流程
|
||
# -----------------------------------------------------------------------------
|
||
main() {
|
||
trap 'log_message "ERROR" "${APP_NAME} 的备份任务出现错误! 终止"' ERR
|
||
log_message "INFO" "====== 开始 ${APP_NAME} 备份任务 ======"
|
||
|
||
# -------------------------------------------------------------------------
|
||
# 步骤 1: 在远程服务器中创建数据库转储
|
||
#
|
||
# 使用 mariadb-dump 从容器中导出数据库,并将结果重定向到 RAM 磁盘目录。
|
||
# 由于磁盘 IO 慢,转储文件直接写入 RAM 磁盘可以减少时间。
|
||
# 注意: 为防止密码泄露,请保证 DB_PASSWORD 不在 shell 历史中。
|
||
# -------------------------------------------------------------------------
|
||
log_message "INFO" "[Step 1/7] 在远程 p3 上导出 Firefly III 数据库..."
|
||
local dump_filename="firefly-db_backup_$(date +%Y%m%d-%H%M%S).sql"
|
||
local remote_dump_path="${REMOTE_DB_RAMDIR}/${dump_filename}"
|
||
local dump_cmd="docker exec ${REMOTE_DB_CONTAINER} mariadb-dump --single-transaction -h localhost -u ${DB_USER} -p'${DB_PASSWORD}' ${DB_NAME} > ${remote_dump_path}"
|
||
execute_remote_command "${REMOTE_USER}" "${REMOTE_HOST}" "${dump_cmd}"
|
||
|
||
# -------------------------------------------------------------------------
|
||
# 步骤 2: Rsync 同步数据库转储和上传目录到备份中心
|
||
#
|
||
# 将远程的 RAM 磁盘数据复制到本地目录。这里创建子目录以避免命名冲突。
|
||
# -------------------------------------------------------------------------
|
||
log_message "INFO" "[Step 2/7] rsync 复制远程数据到备份中心..."
|
||
mkdir -p "${LOCAL_BACKUP_DIR}/upload"
|
||
# 同步上传目录
|
||
rsync -avz --delete --progress -e "ssh -p ${REMOTE_SSH_PORT}" \
|
||
"${REMOTE_USER}@${REMOTE_HOST}:${REMOTE_UPLOAD_DIR}/" \
|
||
"${LOCAL_BACKUP_DIR}/upload/"
|
||
# 同步数据库转储
|
||
rsync -avz --progress -e "ssh -p ${REMOTE_SSH_PORT}" \
|
||
"${REMOTE_USER}@${REMOTE_HOST}:${remote_dump_path}" \
|
||
"${LOCAL_BACKUP_DIR}/"
|
||
|
||
# 可选: 若需备份配置文件,可在此加入 rsync 命令复制 .env 和 docker-compose.yml
|
||
# 例如:rsync -avz "${REMOTE_USER}@${REMOTE_HOST}:/path/to/compose/.env" "${LOCAL_BACKUP_DIR}/"
|
||
|
||
# -------------------------------------------------------------------------
|
||
# 步骤 3: 远程清理数据库转储
|
||
#
|
||
# 删除 p3 上的临时 .sql 文件,防止 RAM 磁盘占用。
|
||
# -------------------------------------------------------------------------
|
||
log_message "INFO" "[Step 3/7] 清理远程数据库转储文件..."
|
||
execute_remote_command "${REMOTE_USER}" "${REMOTE_HOST}" "rm -f ${remote_dump_path}"
|
||
|
||
# -------------------------------------------------------------------------
|
||
# 步骤 4: 本地加密压缩
|
||
#
|
||
# 使用 7‑zip 加密并压缩整个本地备份目录。压缩包命名包含时间戳。
|
||
# -------------------------------------------------------------------------
|
||
log_message "INFO" "[Step 4/7] 使用 7zip 加密本地备份目录..."
|
||
local archive_file="${SCRIPT_RUN_DIR}/${APP_NAME}-backup-$(date +%Y%m%d-%H%M%S).7z"
|
||
encrypt_with_7zip "${LOCAL_BACKUP_DIR}" "${archive_file}"
|
||
|
||
# -------------------------------------------------------------------------
|
||
# 步骤 5: rclone 上传加密包
|
||
# -------------------------------------------------------------------------
|
||
log_message "INFO" "[Step 5/7] 上传加密压缩包至冷存储 => ${RCLONE_REMOTE_REPO}..."
|
||
rclone_copy "${archive_file}" "${RCLONE_REMOTE_REPO}"
|
||
|
||
# -------------------------------------------------------------------------
|
||
# 步骤 6: 控制远程仓库副本数
|
||
# -------------------------------------------------------------------------
|
||
log_message "INFO" "[Step 6/7] 控制远程备份副本数量为 ${MAX_ENCRYPTED_REPLICAS}..."
|
||
rclone_control_replicas "${RCLONE_REMOTE_REPO}" "${APP_NAME}-backup-" "${MAX_ENCRYPTED_REPLICAS}"
|
||
|
||
# -------------------------------------------------------------------------
|
||
# 步骤 7: 本地清理
|
||
#
|
||
# 删除本地生成的加密压缩包,以节省磁盘空间。可根据需要删除同步目录。
|
||
# -------------------------------------------------------------------------
|
||
log_message "INFO" "[Step 7/7] 清理本地加密压缩包..."
|
||
cleanup_local_encrypted_files "${SCRIPT_RUN_DIR}"
|
||
# 可选: rm -rf "${LOCAL_BACKUP_DIR}"
|
||
|
||
log_message "INFO" "====== ${APP_NAME} 备份任务已全部完成! ======"
|
||
}
|
||
|
||
main "$@" |