Files
shell-scripts/0-部署应用/CloudCone-备份中心/firefly-iii-backup.sh
zeaslity 87c9529a2f 新增firefly引用部署
优化clash verge的DNS问题-极致优化
2026-01-07 10:47:52 +08:00

127 lines
6.8 KiB
Bash
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/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: 本地加密压缩
#
# 使用 7zip 加密并压缩整个本地备份目录。压缩包命名包含时间戳。
# -------------------------------------------------------------------------
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 "$@"