diff --git a/0-部署应用/CloudCone-备份中心/b-vault-warden备份.sh b/0-部署应用/CloudCone-备份中心/b-vault-warden备份.sh deleted file mode 100644 index 673b6ea..0000000 --- a/0-部署应用/CloudCone-备份中心/b-vault-warden备份.sh +++ /dev/null @@ -1,32 +0,0 @@ -#!/bin/bash - -# 定时任务 每天凌晨2点执行 -# 环境变量 -vault_warden_host_ip=s5 - - -remote_fetch_vault_warden_backup_data() { - - ssh -p 22333 root@s5 "docker exec -it vault-warden /vaultwarden backup" - - ssh -p 22333 root@s5 "rm -rf /data/vault-warden/persist-data/db_*.sqlite3" -} - -mkdir -p /tmp/vault_warden_backup_stage/ - - - -rsync -a /data/vault-warden/persist-data/config.json /data/vault-warden/persist-data/rsa_key* /data/vault-warden/persist-data/attachments /data/vault-warden/persist-data/sends /data/vault-warden/persist-data/db_*.sqlite3 /tmp/vault_warden_backup_stage/ - - - -将暂存目录的全部内容打包成最终的归档文件。 -cd /tmp/vault_warden_backup_stage/ -tar -czf vaultwarden-backup-$(date +%Y%m%d-%H%M%S).tar.gz /tmp/vault_warden_backup_stage/* - - -rm -rf /tmp/vault_warden_backup_stage/ - - - - diff --git a/0-部署应用/CloudCone-备份中心/common.sh b/0-部署应用/CloudCone-备份中心/common.sh new file mode 100644 index 0000000..39071bf --- /dev/null +++ b/0-部署应用/CloudCone-备份中心/common.sh @@ -0,0 +1,271 @@ +#!/usr/bin/env bash +# ============================================================================= +# Meta : 公共函数与变量库 +# Version : 1.0.0 +# Author : Bash Shell Senior Development Engineer +# License : MIT +# Description : 为备份脚本体系提供标准化的日志、远程执行、加解密及云存储管理功能。 +# ============================================================================= + +#------------------------------------------------------------------------------ +# 脚本严格模式 +# -e: 命令失败时立即退出 +# -u: 变量未定义时报错 +# -o pipefail: 管道中任一命令失败则整个管道失败 +#------------------------------------------------------------------------------ +set -euo pipefail +IFS=$'\n\t' + +#------------------------------------------------------------------------------ +# 全局常量定义区 +#------------------------------------------------------------------------------ +# > 基础路径配置 +readonly SCRIPT_RUN_DIR="/root/wdd/backup" +readonly LOG_DIR="/root/wdd/backup/logs" + +# > 通用配置 +readonly REMOTE_SSH_PORT="22333" +readonly ENCRYPTION_PASSWORD_7ZIP="SuperWdd.CCC.123" # !!!请务必修改为强密码!!! +readonly RCLONE_REMOTE_REPO="gd-zeaslity:CloneCone-BackUp" # rclone配置的远程仓库名及路径 + +# > 日志级别常量 +readonly LOG_LEVEL_DEBUG=0 +readonly LOG_LEVEL_INFO=1 +readonly LOG_LEVEL_WARN=2 +readonly LOG_LEVEL_ERROR=3 + +# > 默认日志级别 (可被调用脚本覆盖) +CURRENT_LOG_LEVEL=${LOG_LEVEL_INFO} + +# > 颜色输出定义 +readonly C_RED='\033[0;31m' +readonly C_GREEN='\033[0;32m' +readonly C_YELLOW='\033[1;33m' +readonly C_BLUE='\033[0;34m' +readonly C_NC='\033[0m' + +#------------------------------------------------------------------------------ +# 模块依赖检查 +#------------------------------------------------------------------------------ +if ! command -v 7z &> /dev/null || ! command -v rclone &> /dev/null || ! command -v ssh &> /dev/null; then + echo -e "${C_RED}[ERROR] Essential commands (7z, rclone, ssh) are not installed. Aborting.${C_NC}" >&2 + exit 1 +fi + +# ============================================================================= +# 函数定义区 +# ============================================================================= + +### +# 功能描述段: 记录标准化的分级日志 +# @param level 日志级别 (DEBUG/INFO/WARN/ERROR) +# @param message 要记录的日志消息 +# @return <0> 成功 +# @require LOG_DIR, CURRENT_LOG_LEVEL +### +log_message() { + local level="$1" + local message="$2" + local log_level_value + local log_file + + log_file="${LOG_DIR}/backup_$(date +%Y%m%d).log" + mkdir -p "${LOG_DIR}" + + case "${level}" in + "DEBUG") log_level_value=${LOG_LEVEL_DEBUG} ;; + "INFO") log_level_value=${LOG_LEVEL_INFO} ;; + "WARN") log_level_value=${LOG_LEVEL_WARN} ;; + "ERROR") log_level_value=${LOG_LEVEL_ERROR} ;; + *) log_level_value=${LOG_LEVEL_INFO} ;; + esac + + if [[ ${CURRENT_LOG_LEVEL} -le ${log_level_value} ]]; then + local timestamp + timestamp=$(date '+%Y-%m-%d %H:%M:%S') + local color_prefix="${C_GREEN}" + + case "${level}" in + "DEBUG") color_prefix="${C_BLUE}" ;; + "INFO") color_prefix="${C_GREEN}" ;; + "WARN") color_prefix="${C_YELLOW}" ;; + "ERROR") color_prefix="${C_RED}" ;; + esac + + # > 格式化日志条目 + local log_entry + log_entry=$(printf "[%-5s] %s: %s" "${level}" "${timestamp}" "${message}") + + # > 输出到标准输出/错误 + echo -e "${color_prefix}${log_entry}${C_NC}" + + # > INFO及以上级别写入日志文件 + if [[ ${log_level_value} -ge ${LOG_LEVEL_INFO} ]]; then + echo "${log_entry}" >> "${log_file}" + fi + fi + return 0 +} + +### +# 功能描述段: 通过SSH在远程主机上安全地执行命令 +# @param remote_user 远程主机用户名 +# @param remote_host 远程主机名或IP地址 +# @param remote_command 待执行的命令 +# @param ssh_port SSH端口 (可选, 默认22333) +# @return 远程命令的退出码 +# @require REMOTE_SSH_PORT, ssh client +### +execute_remote_command() { + local remote_user="$1" + local remote_host="$2" + local remote_command="$3" + local ssh_port=${4:-${REMOTE_SSH_PORT}} + + log_message "DEBUG" "Executing on [${remote_user}@${remote_host}:${ssh_port}]: ${remote_command}" + + ssh -p "${ssh_port}" "${remote_user}@${remote_host}" "${remote_command}" + local exit_code=$? + + if [[ ${exit_code} -ne 0 ]]; then + log_message "ERROR" "Remote command failed with exit code ${exit_code}." + return ${exit_code} + fi + + log_message "DEBUG" "Remote command executed successfully." + return 0 +} + + +### +# 功能描述段: 使用7zip加密并压缩指定目录 +# @param source_directory 需要压缩的源目录路径 +# @param archive_path 生成的加密压缩包完整路径 +# @return <0> 成功 | >0 失败 +# @require ENCRYPTION_PASSWORD_7ZIP, 7z command +### +encrypt_with_7zip() { + local source_directory="$1" + local archive_path="$2" + + if [[ ! -d "${source_directory}" ]]; then + log_message "ERROR" "Source directory for encryption does not exist: ${source_directory}" + return 1 + fi + + log_message "INFO" "Encrypting '${source_directory}' to '${archive_path}'..." + + # > -mhe=on: 加密文件头, 防止泄露文件列表 + # > -p: 指定密码 + 7z a -mhe=on -p"${ENCRYPTION_PASSWORD_7ZIP}" "${archive_path}" "${source_directory}"/* + local exit_code=$? + + if [[ ${exit_code} -ne 0 ]]; then + log_message "ERROR" "7zip encryption failed with exit code ${exit_code}." + return ${exit_code} + fi + + log_message "INFO" "Encryption completed successfully." + return 0 +} + +### +# 功能描述段: 使用rclone将本地文件复制到远程仓库 +# @param source_file 本地源文件路径 +# @param remote_destination rclone远程目标路径 (e.g., "google-drive:backup/app1/") +# @return <0> 成功 | >0 失败 +# @require rclone command +### +rclone_copy() { + local source_file="$1" + local remote_destination="$2" + + if [[ ! -f "${source_file}" ]]; then + log_message "ERROR" "Source file for rclone copy does not exist: ${source_file}" + return 1 + fi + + log_message "INFO" "Copying '${source_file}' to remote '${remote_destination}'..." + + rclone copy -P "${source_file}" "${remote_destination}" + local exit_code=$? + + if [[ ${exit_code} -ne 0 ]]; then + log_message "ERROR" "rclone copy failed with exit code ${exit_code}." + return ${exit_code} + fi + + log_message "INFO" "rclone copy completed successfully." + return 0 +} + + +### +# 功能描述段: 控制rclone远程仓库中的副本数量,删除最旧的副本 +# @param remote_path 远程仓库中的目录路径 +# @param file_prefix 需要管理副本数量的文件名前缀 +# @param max_replicas 允许保留的最大副本数量 +# @return <0> 成功 | >0 失败 +# @require rclone command +### +rclone_control_replicas() { + local remote_path="$1" + local file_prefix="$2" + local max_replicas="$3" + + log_message "INFO" "Checking replicas for '${file_prefix}*' in '${remote_path}'. Max allowed: ${max_replicas}." + + # > 获取远程文件列表及其修改时间 + local remote_files + remote_files=$(rclone lsf --format "tp" "${remote_path}" | grep "${file_prefix}" || true) + + if [[ -z "${remote_files}" ]]; then + log_message "INFO" "No remote files found with prefix '${file_prefix}'. Nothing to do." + return 0 + fi + + local file_count + file_count=$(echo "${remote_files}" | wc -l) + + if [[ ${file_count} -le ${max_replicas} ]]; then + log_message "INFO" "Current replica count (${file_count}) is within the limit (${max_replicas})." + return 0 + fi + + local files_to_delete_count + files_to_delete_count=$((file_count - max_replicas)) + log_message "WARN" "Exceeding replica limit. Need to delete ${files_to_delete_count} oldest file(s)." + + # > 按时间排序并提取需要删除的文件名 + local files_to_delete + files_to_delete=$(echo "${remote_files}" | sort -k2 | head -n "${files_to_delete_count}" | awk -F';' '{print $1}') + + for file in ${files_to_delete}; do + log_message "INFO" "Deleting oldest replica: ${file}" + rclone deletefile "${remote_path}/${file}" + if [[ $? -ne 0 ]]; then + log_message "ERROR" "Failed to delete remote file: ${file}" + # > 继续尝试删除其他文件,不立即失败 + fi + done + + log_message "INFO" "Replica control process finished." + return 0 +} + +### +# 功能描述段: 清理指定目录下的所有.7z加密压缩包 +# @param target_directory 需要清理的目录路径 +# @return <0> 成功 +# @require find command +### +cleanup_local_encrypted_files() { + local target_directory="$1" + + log_message "INFO" "Cleaning up local encrypted files (*.7z) in '${target_directory}'..." + + find "${target_directory}" -maxdepth 1 -type f -name "*.7z" -delete + + log_message "INFO" "Local cleanup finished." + return 0 +} diff --git a/0-部署应用/CloudCone-备份中心/deepseek-v3.1/b-gitea-dsv3.1.sh b/0-部署应用/CloudCone-备份中心/deepseek-v3.1/b-gitea-dsv3.1.sh new file mode 100644 index 0000000..a5e6b1c --- /dev/null +++ b/0-部署应用/CloudCone-备份中心/deepseek-v3.1/b-gitea-dsv3.1.sh @@ -0,0 +1,264 @@ +#!/usr/bin/env bash +# +# Gitea 远程备份脚本 +# Author: System Administrator +# Version: 1.0.0 +# License: MIT +# +# 功能描述:通过SSH远程执行Gitea备份操作,并将备份文件同步到本地 +# 依赖要求:ssh, rsync, docker, date, grep, awk 等基础工具 + +set -euo pipefail +IFS=$'\n\t' + +################################################################################ +# 全局常量定义区 +################################################################################ + +readonly REMOTE_PORT="22333" +readonly REMOTE_HOST="t0" +readonly SCRIPT_DIR="/root/wdd/backup" +readonly REMOTE_GITEA_CONTAINER="gitea-gitea-1" +readonly REMOTE_GITEA_CONFIG="/bitnami/gitea/custom/conf/app.ini" +readonly REMOTE_BACKUP_SOURCE="/data/gitea/gitea_data/data/tmp/gitea-dump-*.zip" +readonly LOCAL_BACKUP_TARGET="/data/t0_150_230_198_103/gitea/" + +# > 日志配置 +readonly LOG_DIR="${SCRIPT_DIR}/logs" +readonly LOG_FILE="${LOG_DIR}/gitea_backup_$(date +%Y%m%d).log" + +# 日志级别常量 +readonly LOG_LEVEL_DEBUG=0 +readonly LOG_LEVEL_INFO=1 +readonly LOG_LEVEL_WARN=2 +readonly LOG_LEVEL_ERROR=3 + +# 当前日志级别(默认INFO) +CURRENT_LOG_LEVEL=${LOG_LEVEL_INFO} + +################################################################################ +# 函数声明区 +################################################################################ + +# 输出格式化日志信息(同时输出到控制台和日志文件) +# @param level string 日志级别(DEBUG/INFO/WARN/ERROR) +# @param message string 日志消息内容 +# @return void +# @require CURRENT_LOG_LEVEL, LOG_FILE +log_message() { + local level="$1" + local message="$2" + local timestamp + timestamp=$(date '+%Y-%m-%d %H:%M:%S') + local log_entry="" + case "$level" in + "DEBUG") + if [ "${CURRENT_LOG_LEVEL}" -le ${LOG_LEVEL_DEBUG} ]; then + log_entry="[DEBUG][${timestamp}] ${message}" + echo "${log_entry}" + echo "${log_entry}" >> "${LOG_FILE}" + fi + ;; + "INFO") + if [ "${CURRENT_LOG_LEVEL}" -le ${LOG_LEVEL_INFO} ]; then + log_entry="[INFO][${timestamp}] ${message}" + echo "${log_entry}" + echo "${log_entry}" >> "${LOG_FILE}" + fi + ;; + "WARN") + if [ "${CURRENT_LOG_LEVEL}" -le ${LOG_LEVEL_WARN} ]; then + log_entry="[WARN][${timestamp}] ${message}" + echo "${log_entry}" >&2 + echo "${log_entry}" >> "${LOG_FILE}" + fi + ;; + "ERROR") + if [ "${CURRENT_LOG_LEVEL}" -le ${LOG_LEVEL_ERROR} ]; then + log_entry="[ERROR][${timestamp}] ${message}" + echo "${log_entry}" >&2 + echo "${log_entry}" >> "${LOG_FILE}" + fi + ;; + *) + log_entry="[UNKNOWN][${timestamp}] ${message}" + echo "${log_entry}" >&2 + echo "${log_entry}" >> "${LOG_FILE}" + ;; + esac +} + +### +# 执行远程SSH命令 +# @param command string 需要执行的远程命令 +# @return int 命令执行退出码 +# @require REMOTE_HOST, REMOTE_PORT +execute_remote_command() { + local command="$1" + local exit_code + + log_message "DEBUG" "执行远程命令: ${command}" + + # > 通过SSH连接到远程主机执行命令 + ssh -p "${REMOTE_PORT}" "${REMOTE_HOST}" "${command}" + exit_code=$? + + if [ ${exit_code} -ne 0 ]; then + log_message "ERROR" "远程命令执行失败,退出码: ${exit_code}" + return ${exit_code} + fi + + return 0 +} + +### +# 执行Gitea备份操作 +# @return int 操作执行状态码 +# @require REMOTE_GITEA_CONTAINER, REMOTE_GITEA_CONFIG +perform_gitea_backup() { + local backup_command="docker exec -i ${REMOTE_GITEA_CONTAINER} /opt/bitnami/gitea/bin/gitea dump -c ${REMOTE_GITEA_CONFIG}" + + log_message "INFO" "开始执行Gitea备份..." + + # > 执行Gitea dump命令生成备份文件 + if ! execute_remote_command "${backup_command}"; then + log_message "ERROR" "Gitea备份命令执行失败" + return 1 + fi + + log_message "INFO" "Gitea备份命令执行成功" + return 0 +} + +### +# 重命名备份文件(添加时间戳) +# @return int 操作执行状态码 +# @require REMOTE_GITEA_CONTAINER +rename_backup_file() { + local rename_command="docker exec -i ${REMOTE_GITEA_CONTAINER} /bin/sh -c \"mv /opt/bitnami/gitea/gitea-dump-*.zip /opt/bitnami/gitea/data/tmp/gitea-dump-\$(date +%Y%m%d-%H%M%S).zip\"" + + log_message "INFO" "开始重命名备份文件..." + + # > 在容器内重命名备份文件,添加时间戳 + if ! execute_remote_command "${rename_command}"; then + log_message "ERROR" "备份文件重命名失败" + return 1 + fi + + log_message "INFO" "备份文件重命名成功" + return 0 +} + +### +# 同步备份文件到本地 +# @return int 操作执行状态码 +# @require REMOTE_HOST, REMOTE_PORT, REMOTE_BACKUP_SOURCE, LOCAL_BACKUP_TARGET +sync_backup_to_local() { + log_message "INFO" "开始同步备份文件到本地..." + + # > 创建本地目标目录(如果不存在) + if [ ! -d "${LOCAL_BACKUP_TARGET}" ]; then + mkdir -p "${LOCAL_BACKUP_TARGET}" + log_message "DEBUG" "创建本地目录: ${LOCAL_BACKUP_TARGET}" + fi + + # > 使用rsync同步文件,保留关键属性 + rsync -avz -e "ssh -p ${REMOTE_PORT}" \ + "${REMOTE_HOST}:${REMOTE_BACKUP_SOURCE}" \ + "${LOCAL_BACKUP_TARGET}" + + local exit_code=$? + if [ ${exit_code} -ne 0 ]; then + log_message "ERROR" "rsync同步失败,退出码: ${exit_code}" + return ${exit_code} + fi + + log_message "INFO" "备份文件同步成功" + return 0 +} + +### +# 清理远程备份文件 +# @return int 操作执行状态码 +# @require REMOTE_BACKUP_SOURCE +cleanup_remote_backup() { + local cleanup_command="rm -f ${REMOTE_BACKUP_SOURCE}" + + log_message "INFO" "开始清理远程备份文件..." + + # > 删除远程主机上的临时备份文件 + if ! execute_remote_command "${cleanup_command}"; then + log_message "ERROR" "远程备份文件清理失败" + return 1 + fi + + log_message "INFO" "远程备份文件清理成功" + return 0 +} + +### +# 主执行函数 - 协调整个备份流程 +# @return int 脚本执行最终状态码 +main() { + local overall_success=true + + log_message "INFO" "=== Gitea备份流程开始 ===" + + # 切换到工作目录 + cd "${SCRIPT_DIR}" || { + log_message "ERROR" "无法切换到工作目录: ${SCRIPT_DIR}" + return 1 + } + + # 执行备份流程 + if ! perform_gitea_backup; then + overall_success=false + fi + + if ! rename_backup_file; then + overall_success=false + fi + + if ! sync_backup_to_local; then + overall_success=false + fi + + if ! cleanup_remote_backup; then + overall_success=false + fi + + # 汇总执行结果 + if [ "${overall_success}" = true ]; then + log_message "INFO" "=== Gitea备份流程完成 ===" + return 0 + else + log_message "ERROR" "=== Gitea备份流程部分失败 ===" + return 1 + fi +} + +################################################################################ +# 异常处理设置 +################################################################################ + +# 设置trap捕获信号 +trap 'log_message "ERROR" "脚本被中断"; exit 1' INT TERM + +################################################################################ +# 主执行流程 +################################################################################ + +# 函数调用关系: +# main -> perform_gitea_backup -> execute_remote_command +# -> rename_backup_file -> execute_remote_command +# -> sync_backup_to_local +# -> cleanup_remote_backup -> execute_remote_command + +# 执行主函数 +if main; then + log_message "INFO" "脚本执行成功" + exit 0 +else + log_message "ERROR" "脚本执行失败" + exit 1 +fi diff --git a/0-部署应用/CloudCone-备份中心/deepseek-v3.1/b-nextcloud-dsv3.1.sh b/0-部署应用/CloudCone-备份中心/deepseek-v3.1/b-nextcloud-dsv3.1.sh new file mode 100644 index 0000000..83d4ed6 --- /dev/null +++ b/0-部署应用/CloudCone-备份中心/deepseek-v3.1/b-nextcloud-dsv3.1.sh @@ -0,0 +1,361 @@ +#!/bin/bash +# ============================================================================= +# nextcloud备份脚本 +# 功能:远程Nextcloud维护模式切换、数据库备份、文件同步及清理 +# 版本:1.0.0 +# 作者:Shell脚本工程师 +# 许可证:MIT License +# 依赖:ssh, rsync, docker (远程主机), mariadb-client (远程主机) +# ============================================================================= + +set -euo pipefail +IFS=$'\n\t' + +# > 全局常量定义 +readonly SCRIPT_NAME="$(basename "$0")" +readonly SCRIPT_DIR="/root/wdd/backup" +readonly LOCK_FILE="/root/wdd/backup/${SCRIPT_NAME}.lock" + +# > 远程主机配置 +readonly REMOTE_HOST="s5" +readonly REMOTE_PORT="22333" +readonly REMOTE_USER="root" +readonly REMOTE_NEXTCLOUD_DIR="/data/nextcloud" +readonly REMOTE_DB_CONTAINER="nextcloud-db" +readonly REMOTE_WEB_CONTAINER="nextcloud_web" + +# > 数据库配置 +readonly DB_NAME="nextcloud" +readonly DB_USER="nextcloud" +readonly DB_PASSWORD="boge14@Level5" + +# > 本地配置 +readonly LOCAL_BACKUP_DIR="/data/s5_146-56-159-175/nextcloud" + +# > 日志配置 +readonly LOG_DIR="${SCRIPT_DIR}/logs" +readonly LOG_FILE="${LOG_DIR}/nextcloud_backup_$(date +%Y%m%d).log" + +# > 颜色输出定义 +readonly RED='\033[0;31m' +readonly GREEN='\033[0;32m' +readonly YELLOW='\033[1;33m' +readonly BLUE='\033[0;34m' +readonly NC='\033[0m' + +# ============================================================================= +# 日志函数集 +# ============================================================================= + +### +# 初始化日志系统 +# @require 无 +# @return 0 成功 | >0 失败 +### +init_log_system() { + mkdir -p "${LOG_DIR}" || return 1 + touch "${LOG_FILE}" || return 1 + return 0 +} + +### +# 记录日志消息 +# @param level string 日志级别(DEBUG/INFO/WARN/ERROR) +# @param message string 日志消息 +# @require LOG_FILE +# @return 0 成功 +### +log_message() { + local level="$1" + local message="$2" + local timestamp + timestamp=$(date '+%Y-%m-%d %H:%M:%S') + + case "${level}" in + "DEBUG") echo -e "${BLUE}[DEBUG]${NC} ${timestamp} - ${message}" | tee -a "${LOG_FILE}" ;; + "INFO") echo -e "${GREEN}[INFO]${NC} ${timestamp} - ${message}" | tee -a "${LOG_FILE}" ;; + "WARN") echo -e "${YELLOW}[WARN]${NC} ${timestamp} - ${message}" | tee -a "${LOG_FILE}" >&2 ;; + "ERROR") echo -e "${RED}[ERROR]${NC} ${timestamp} - ${message}" | tee -a "${LOG_FILE}" >&2 ;; + *) echo "${timestamp} - ${message}" | tee -a "${LOG_FILE}" ;; + esac + return 0 +} + +# ============================================================================= +# 工具函数集 +# ============================================================================= + +### +# 检查命令是否存在 +# @param command_name string 命令名称 +# @require 无 +# @return 0 存在 | 1 不存在 +### +check_command() { + local command_name="$1" + if ! command -v "${command_name}" >/dev/null 2>&1; then + log_message "ERROR" "命令不存在: ${command_name}" + return 1 + fi + return 0 +} + +### +# 执行远程SSH命令 +# @param command string 要执行的命令 +# @require REMOTE_HOST, REMOTE_PORT, REMOTE_USER +# @return 远程命令的退出码 +### +execute_remote_command() { + local command="$1" + ssh -p "${REMOTE_PORT}" "${REMOTE_USER}@${REMOTE_HOST}" "${command}" + return $? +} + +### +# 创建锁文件防止并发执行 +# @require LOCK_FILE +# @return 0 成功获取锁 | 1 锁已存在 +### +acquire_lock() { + if [ -e "${LOCK_FILE}" ]; then + log_message "ERROR" "备份任务正在运行或异常退出,请检查锁文件: ${LOCK_FILE}" + return 1 + fi + echo "$$" > "${LOCK_FILE}" + trap 'release_lock' EXIT + return 0 +} + +### +# 释放锁文件 +# @require LOCK_FILE +# @return 0 成功 +### +release_lock() { + [ -e "${LOCK_FILE}" ] && rm -f "${LOCK_FILE}" + return 0 +} + +# ============================================================================= +# Nextcloud核心备份函数 +# ============================================================================= + +### +# 启用Nextcloud维护模式 +# @require execute_remote_command, REMOTE_WEB_CONTAINER +# @return 0 成功 | >0 失败 +### +enable_maintenance_mode() { + log_message "INFO" "启用Nextcloud维护模式..." + + local maintenance_cmd="docker exec -u www-data ${REMOTE_WEB_CONTAINER} php occ maintenance:mode --on" + + if ! execute_remote_command "${maintenance_cmd}"; then + log_message "ERROR" "启用维护模式失败" + return 1 + fi + + log_message "INFO" "维护模式已启用" + return 0 +} + +### +# 禁用Nextcloud维护模式 +# @require execute_remote_command, REMOTE_WEB_CONTAINER +# @return 0 成功 | >0 失败 +### +disable_maintenance_mode() { + log_message "INFO" "禁用Nextcloud维护模式..." + + local maintenance_cmd="docker exec -u www-data ${REMOTE_WEB_CONTAINER} php occ maintenance:mode --off" + + if ! execute_remote_command "${maintenance_cmd}"; then + log_message "ERROR" "禁用维护模式失败" + return 1 + fi + + log_message "INFO" "维护模式已禁用" + return 0 +} + +### +# 远程执行MariaDB数据库备份 +# @require execute_remote_command, REMOTE_DB_CONTAINER, DB_NAME, DB_USER, DB_PASSWORD, REMOTE_NEXTCLOUD_DIR +# @return 0 成功 | >0 失败 +### +backup_database() { + log_message "INFO" "开始数据库备份..." + + local backup_file="${REMOTE_NEXTCLOUD_DIR}/nextcloud-db_backup_$(date +%Y%m%d-%H%M%S).sql" + local backup_cmd="docker exec ${REMOTE_DB_CONTAINER} mariadb-dump --single-transaction -h localhost -u ${DB_USER} -p'${DB_PASSWORD}' ${DB_NAME} > ${backup_file}" + + if ! execute_remote_command "${backup_cmd}"; then + log_message "ERROR" "数据库备份失败" + return 1 + fi + + # > 验证备份文件是否创建成功 + local verify_cmd="[ -f \"${backup_file}\" ] && echo \"exists\" || echo \"missing\"" + if [ "$(execute_remote_command "${verify_cmd}")" != "exists" ]; then + log_message "ERROR" "数据库备份文件创建失败" + return 1 + fi + + log_message "INFO" "数据库备份完成: ${backup_file}" + return 0 +} + +### +# 使用rsync同步Nextcloud文件到本地 +# @require REMOTE_HOST, REMOTE_PORT, REMOTE_USER, REMOTE_NEXTCLOUD_DIR, LOCAL_BACKUP_DIR +# @return 0 成功 | >0 失败 +### +sync_nextcloud_files() { + log_message "INFO" "开始同步Nextcloud文件到本地..." + + # > 创建本地暂存目录 + mkdir -p "${LOCAL_BACKUP_DIR}" || { + log_message "ERROR" "创建本地暂存目录失败: ${LOCAL_BACKUP_DIR}" + return 1 + } + + # > 构建rsync命令 + local rsync_cmd="rsync -avz --progress -e 'ssh -p ${REMOTE_PORT}'" + rsync_cmd+=" ${REMOTE_USER}@${REMOTE_HOST}:${REMOTE_NEXTCLOUD_DIR}/" + rsync_cmd+=" ${LOCAL_BACKUP_DIR}/" + + # > 执行rsync同步 + if ! eval "${rsync_cmd}"; then + log_message "ERROR" "Nextcloud文件同步失败" + return 1 + fi + + log_message "INFO" "Nextcloud文件同步完成" + return 0 +} + + +### +# 远程删除数据库备份文件 +# @require execute_remote_command, REMOTE_NEXTCLOUD_DIR +# @return 0 成功 | >0 失败 +### +remote_cleanup_backup() { + log_message "INFO" "清理远程数据库备份文件..." + + local cleanup_cmd="rm -f ${REMOTE_NEXTCLOUD_DIR}/nextcloud-db_backup_*.sql" + + if ! execute_remote_command "${cleanup_cmd}"; then + log_message "ERROR" "远程清理失败" + return 1 + fi + + log_message "INFO" "远程清理完成" + return 0 +} + +### +# 清理本地暂存目录 +# @require LOCAL_BACKUP_DIR +# @return 0 成功 +### +local_cleanup() { + log_message "INFO" "清理本地暂存目录..." + [ -d "${LOCAL_BACKUP_DIR}" ] && rm -rf "${LOCAL_BACKUP_DIR}" + return 0 +} + +# ============================================================================= +# 主执行流程 +# ============================================================================= + +### +# 主备份流程 +# @require 所有上述函数 +# @return 0 成功 | >0 失败 +### +main_backup_process() { + log_message "INFO" "=== 开始Nextcloud备份任务 ===" + + # > 检查依赖命令 + local required_commands=("ssh" "rsync") + for cmd in "${required_commands[@]}"; do + if ! check_command "${cmd}"; then + return 1 + fi + done + + # > 执行备份流程 + local steps=( + enable_maintenance_mode + backup_database + sync_nextcloud_files + remote_cleanup_backup + disable_maintenance_mode +# local_cleanup + ) + + for step in "${steps[@]}"; do + if ! "${step}"; then + log_message "ERROR" "备份任务失败,正在尝试恢复..." + # > 尝试禁用维护模式 + disable_maintenance_mode || true + return 1 + fi + done + + log_message "INFO" "=== Nextcloud备份任务完成 ===" + return 0 +} + +# ============================================================================= +# 脚本入口点 +# ============================================================================= + +# > 设置错误处理 +trap 'log_message "ERROR" "脚本异常退出"; disable_maintenance_mode || true; release_lock; exit 1' ERR + +# > 主执行块 +main() { + if ! acquire_lock; then + exit 1 + fi + + if ! init_log_system; then + log_message "ERROR" "日志系统初始化失败" + exit 1 + fi + + if ! main_backup_process; then + log_message "ERROR" "备份任务执行失败" + exit 1 + fi + + release_lock + exit 0 +} + +# > 脚本执行入口 +main "$@" + +# ============================================================================= +# 函数调用关系图 +# ============================================================================= +# main +# ├── acquire_lock +# ├── init_log_system +# └── main_backup_process +# ├── check_command (多次调用) +# ├── enable_maintenance_mode +# │ └── execute_remote_command +# ├── backup_database +# │ └── execute_remote_command +# ├── sync_nextcloud_files +# ├── move_to_backup_dir +# ├── remote_cleanup_backup +# │ └── execute_remote_command +# ├── disable_maintenance_mode +# │ └── execute_remote_command +# └── local_cleanup + diff --git a/0-部署应用/CloudCone-备份中心/b-vault-warden-dsv3.1.sh b/0-部署应用/CloudCone-备份中心/deepseek-v3.1/b-vault-warden-dsv3.1.sh similarity index 91% rename from 0-部署应用/CloudCone-备份中心/b-vault-warden-dsv3.1.sh rename to 0-部署应用/CloudCone-备份中心/deepseek-v3.1/b-vault-warden-dsv3.1.sh index 5d366ff..46f89bb 100644 --- a/0-部署应用/CloudCone-备份中心/b-vault-warden-dsv3.1.sh +++ b/0-部署应用/CloudCone-备份中心/deepseek-v3.1/b-vault-warden-dsv3.1.sh @@ -13,8 +13,8 @@ IFS=$'\n\t' # > 全局常量定义 readonly SCRIPT_NAME="$(basename "$0")" -readonly SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" -readonly LOCK_FILE="/tmp/${SCRIPT_NAME}.lock" +readonly SCRIPT_DIR="/root/wdd/backup" +readonly LOCK_FILE="/root/wdd/backup/${SCRIPT_NAME}.lock" # > 配置参数(可根据需要调整为环境变量) readonly REMOTE_HOST="s5" @@ -22,20 +22,20 @@ readonly REMOTE_PORT="22333" readonly REMOTE_USER="root" readonly REMOTE_BACKUP_CMD="docker exec vault-warden /vaultwarden backup" readonly REMOTE_DATA_DIR="/data/vault-warden/persist-data" -readonly LOCAL_STAGE_DIR="/tmp/vault_warden_backup_stage" -readonly LOCAL_BACKUP_DIR="${SCRIPT_DIR}/backups" +readonly LOCAL_BACKUP_DIR="/data/s5_146-56-159-175/vault_warden" readonly BACKUP_PATTERNS=( "config.json" "rsa_key*" "attachments" + "icon_cache" "sends" "db_*.sqlite3" ) -readonly ENCRYPTION_PASSWORD="your_encryption_password_here" # > 请在实际使用时修改 +readonly ENCRYPTION_PASSWORD="SuperWdd.123" # > 请在实际使用时修改 # > 日志配置 readonly LOG_DIR="${SCRIPT_DIR}/logs" -readonly LOG_FILE="${LOG_DIR}/backup_$(date +%Y%m%d).log" +readonly LOG_FILE="${LOG_DIR}/vault_warden_backup_$(date +%Y%m%d).log" # > 颜色输出定义 readonly RED='\033[0;31m' @@ -161,15 +161,15 @@ remote_execute_backup() { ### # 使用rsync同步备份文件到本地 -# @require REMOTE_HOST, REMOTE_PORT, REMOTE_USER, REMOTE_DATA_DIR, LOCAL_STAGE_DIR, BACKUP_PATTERNS +# @require REMOTE_HOST, REMOTE_PORT, REMOTE_USER, REMOTE_DATA_DIR, LOCAL_BACKUP_DIR, BACKUP_PATTERNS # @return 0 成功 | >0 失败 ### sync_backup_files() { log_message "INFO" "开始同步备份文件到本地..." # > 创建本地暂存目录 - mkdir -p "${LOCAL_STAGE_DIR}" || { - log_message "ERROR" "创建本地暂存目录失败: ${LOCAL_STAGE_DIR}" + mkdir -p "${LOCAL_BACKUP_DIR}" || { + log_message "ERROR" "创建本地暂存目录失败: ${LOCAL_BACKUP_DIR}" return 1 } @@ -180,7 +180,7 @@ sync_backup_files() { rsync_cmd+=" ${REMOTE_USER}@${REMOTE_HOST}:${REMOTE_DATA_DIR}/${pattern}" done - rsync_cmd+=" ${LOCAL_STAGE_DIR}/" + rsync_cmd+=" ${LOCAL_BACKUP_DIR}/" # > 执行rsync同步 if ! eval "${rsync_cmd}"; then @@ -194,7 +194,7 @@ sync_backup_files() { ### # 使用7zip加密压缩备份文件 -# @require LOCAL_STAGE_DIR, LOCAL_BACKUP_DIR, ENCRYPTION_PASSWORD +# @require LOCAL_BACKUP_DIR, LOCAL_BACKUP_DIR, ENCRYPTION_PASSWORD # @return 0 成功 | >0 失败 ### encrypt_and_compress() { @@ -215,7 +215,7 @@ encrypt_and_compress() { local backup_file="${LOCAL_BACKUP_DIR}/vaultwarden-backup-$(date +%Y%m%d-%H%M%S).7z" # > 执行加密压缩 - if ! (cd "${LOCAL_STAGE_DIR}" && 7z a -p"${ENCRYPTION_PASSWORD}" -mhe=on "${backup_file}" . >/dev/null); then + if ! (cd "${LOCAL_BACKUP_DIR}" && 7z a -p"${ENCRYPTION_PASSWORD}" -mhe=on "${backup_file}" . >/dev/null); then log_message "ERROR" "加密压缩失败" return 1 fi @@ -245,12 +245,12 @@ remote_cleanup_backup() { ### # 清理本地暂存目录 -# @require LOCAL_STAGE_DIR +# @require LOCAL_BACKUP_DIR # @return 0 成功 ### local_cleanup() { log_message "INFO" "清理本地暂存目录..." - [ -d "${LOCAL_STAGE_DIR}" ] && rm -rf "${LOCAL_STAGE_DIR}" + [ -d "${LOCAL_BACKUP_DIR}" ] && rm -rf "${LOCAL_BACKUP_DIR}" return 0 } @@ -280,7 +280,7 @@ main_backup_process() { sync_backup_files encrypt_and_compress remote_cleanup_backup - local_cleanup +# local_cleanup ) for step in "${steps[@]}"; do diff --git a/0-部署应用/CloudCone-备份中心/gitea-backup.sh b/0-部署应用/CloudCone-备份中心/gitea-backup.sh new file mode 100644 index 0000000..9de1340 --- /dev/null +++ b/0-部署应用/CloudCone-备份中心/gitea-backup.sh @@ -0,0 +1,90 @@ +#!/usr/bin/env bash +# ============================================================================= +# Meta : Gitea 备份执行脚本 +# Version : 2.0.0 +# Author : Bash Shell Senior Development Engineer +# License : MIT +# Description : 自动化执行Gitea远程备份、同步、加密、上传及清理任务。 +# ============================================================================= + +source "$(dirname "$0")/common.sh" || { echo "FATAL: common.sh not found." >&2; exit 1; } + +#------------------------------------------------------------------------------ +# 脚本配置区 +#------------------------------------------------------------------------------ +readonly APP_NAME="Gitea" +readonly REMOTE_USER="root" +readonly REMOTE_HOST="t0" +readonly MAX_ENCRYPTED_REPLICAS=4 + +# > 远程配置 +readonly REMOTE_CONTAINER="gitea-gitea-1" +readonly REMOTE_GITEA_CONF="/bitnami/gitea/custom/conf/app.ini" +readonly REMOTE_TMP_DIR="/opt/bitnami/gitea/data/tmp" +readonly REMOTE_RSYNC_SOURCE_DIR="/data/gitea/gitea_data/data/tmp/" # 注意末尾的斜杠 + +# > 本地路径 +readonly LOCAL_BACKUP_DIR="/data/t0_150_230_198_103/gitea" + +# ============================================================================= +# 主执行流程 +# ============================================================================= +main() { + trap 'log_message "ERROR" "${APP_NAME}的备份任务出现错误! 终止"' ERR + log_message "INFO" "====== 开始 ${APP_NAME} 备份任务 ======" + + # > 步骤 1: 执行Gitea备份命令 + log_message "INFO" "[Step 1/8] 远程执行${APP_NAME} 备份 DUMP..." + local dump_cmd="docker exec ${REMOTE_CONTAINER} /opt/bitnami/gitea/bin/gitea dump -c ${REMOTE_GITEA_CONF}" + execute_remote_command "${REMOTE_USER}" "${REMOTE_HOST}" "${dump_cmd}" + + # > 步骤 2: 移动并重命名备份文件 + log_message "INFO" "[Step 2/8] 移动并重命名备份文件..." + local new_filename="gitea-dump-$(date +%Y%m%d-%H%M%S).zip" + local move_cmd="docker exec ${REMOTE_CONTAINER} /bin/sh -c 'mv /opt/bitnami/gitea/gitea-dump-*.zip ${REMOTE_TMP_DIR}/${new_filename}'" + execute_remote_command "${REMOTE_USER}" "${REMOTE_HOST}" "${move_cmd}" + + # > 步骤 3: rsync复制备份文件到本地 + log_message "INFO" "[Step 3/8] rsync复制备份文件到本地..." + mkdir -p "${LOCAL_BACKUP_DIR}" + rsync -avz --progress -e "ssh -p ${REMOTE_SSH_PORT}" \ + "${REMOTE_USER}@${REMOTE_HOST}:${REMOTE_RSYNC_SOURCE_DIR}${new_filename}" \ + "${LOCAL_BACKUP_DIR}/" + + # > 步骤 4: 远程清理备份文件 + log_message "INFO" "[Step 4/8] Cleaning up remote dump file..." + execute_remote_command "${REMOTE_USER}" "${REMOTE_HOST}" "rm -f ${REMOTE_RSYNC_SOURCE_DIR}gitea-dump-*.zip" + + # > 步骤 5: 7zip加密 + local archive_file="${SCRIPT_RUN_DIR}/${APP_NAME}-backup-$(date +%Y%m%d-%H%M%S).7z" + log_message "INFO" "[Step 5/8] 开始加密本地备份目录..." + encrypt_with_7zip "${LOCAL_BACKUP_DIR}" "${archive_file}" + + # > 步骤 6: rclone上传 + log_message "INFO" "[Step 6/8] 上传加密压缩包至冷存储 => ${RCLONE_REMOTE_REPO}..." + rclone_copy "${archive_file}" "${RCLONE_REMOTE_REPO}" + + # > 步骤 7: 控制远程副本数 + log_message "INFO" "[Step 7/8] 控制冷备份的副本数量 => ${MAX_ENCRYPTED_REPLICAS}..." + rclone_control_replicas "${RCLONE_REMOTE_REPO}" "${APP_NAME}-backup-" "${MAX_ENCRYPTED_REPLICAS}" + + # > 步骤 8: 清理本地 + log_message "INFO" "[Step 8/8] 清理本地压缩包..." + cleanup_local_encrypted_files "${SCRIPT_RUN_DIR}" + # rm -rf "${LOCAL_BACKUP_DIR}" + + log_message "INFO" "====== ${APP_NAME} 备份任务已全部完成! ======" +} + +# ============================================================================= +# 脚本入口点 +# ============================================================================= +# 函数调用关系图 +# main +# ├─ execute_remote_command (4) +# ├─ encrypt_with_7zip +# ├─ rclone_copy +# ├─ rclone_control_replicas +# └─ cleanup_local_encrypted_files +# ============================================================================= +main "$@" diff --git a/0-部署应用/CloudCone-备份中心/next-cloud-backup.sh b/0-部署应用/CloudCone-备份中心/next-cloud-backup.sh new file mode 100644 index 0000000..d185dc2 --- /dev/null +++ b/0-部署应用/CloudCone-备份中心/next-cloud-backup.sh @@ -0,0 +1,111 @@ +#!/usr/bin/env bash +# ============================================================================= +# Meta : NextCloud 备份执行脚本 +# Version : 2.0.0 +# Author : Bash Shell Senior Development Engineer +# License : MIT +# Description : 自动化执行NextCloud维护模式切换、数据库和文件备份、加密、上传及清理。 +# ============================================================================= + +source "$(dirname "$0")/common.sh" || { echo "FATAL: common.sh not found." >&2; exit 1; } + +#------------------------------------------------------------------------------ +# 脚本配置区 +#------------------------------------------------------------------------------ +readonly APP_NAME="NextCloud" +readonly REMOTE_USER="root" +readonly REMOTE_HOST="s5" +readonly MAX_ENCRYPTED_REPLICAS=3 + +# > 远程配置 +readonly REMOTE_WEB_CONTAINER="nextcloud_web" +readonly REMOTE_DB_CONTAINER="nextcloud-db" +readonly REMOTE_DATA_DIR="/data/nextcloud" +readonly DB_USER="nextcloud" +readonly DB_PASSWORD="boge14@Level5" # 建议使用更安全的方式管理密码 +readonly DB_NAME="nextcloud" + +# > 本地路径 +readonly LOCAL_BACKUP_DIR="/data/s5_146-56-159-175/nextcloud" + +# ============================================================================= +# 核心函数 +# ============================================================================= +### +# 功能描述段: 切换Nextcloud维护模式 (on/off) +# @param mode 模式, 'on' 或 'off' +# @return <0> 成功 | >0 失败 +### +toggle_maintenance_mode() { + local mode="$1" + log_message "INFO" "Setting maintenance mode to '${mode}'..." + execute_remote_command "${REMOTE_USER}" "${REMOTE_HOST}" \ + "docker exec -u www-data ${REMOTE_WEB_CONTAINER} php occ maintenance:mode --${mode}" +} + +# ============================================================================= +# 主执行流程 +# ============================================================================= +main() { + # > 设置陷阱,确保任何情况下都能尝试关闭维护模式 + trap 'log_message "ERROR" "${APP_NAME}中止的备份任务。试图禁用维护模式..."; toggle_maintenance_mode "off" || true; exit 1' ERR + + log_message "INFO" "${APP_NAME}的备份任务出现错误! 终止! " + + # > 步骤 1: 启用维护模式 + log_message "INFO" "[Step 1/8] 启用维护模式..." + toggle_maintenance_mode "on" + + # > 步骤 2: 数据库备份 + log_message "INFO" "[Step 2/8] 执行远程数据库备份..." + local db_backup_file="${REMOTE_DATA_DIR}/nextcloud-db_backup_$(date +%Y%m%d-%H%M%S).sql" + local db_backup_cmd="docker exec ${REMOTE_DB_CONTAINER} mariadb-dump --single-transaction -h localhost -u ${DB_USER} -p'${DB_PASSWORD}' ${DB_NAME} > ${db_backup_file}" + execute_remote_command "${REMOTE_USER}" "${REMOTE_HOST}" "${db_backup_cmd}" + + # > 步骤 3: rsync复制备份文件 + log_message "INFO" "[Step 3/8] Srsync复制远程备份文件..." + mkdir -p "${LOCAL_BACKUP_DIR}" + rsync -avz --progress -e "ssh -p ${REMOTE_SSH_PORT}" \ + "${REMOTE_USER}@${REMOTE_HOST}:${REMOTE_DATA_DIR}/" \ + "${LOCAL_BACKUP_DIR}/" + + # > 步骤 4: 远程清理数据库备份 + log_message "INFO" "[Step 4/8] 远程清理数据库备份..." + execute_remote_command "${REMOTE_USER}" "${REMOTE_HOST}" "rm -f ${REMOTE_DATA_DIR}/nextcloud-db_backup_*.sql" + + # > 步骤 5: 禁用维护模式 + log_message "INFO" "[Step 5/8] 禁用维护模式..." + toggle_maintenance_mode "off" + + # > 步骤 6: 7zip加密 + local archive_file="${SCRIPT_RUN_DIR}/${APP_NAME}-backup-$(date +%Y%m%d-%H%M%S).7z" + log_message "INFO" "[Step 6/8] 7zip加密本地目录..." + encrypt_with_7zip "${LOCAL_BACKUP_DIR}" "${archive_file}" + + # > 步骤 7: rclone上传 + log_message "INFO" "[Step 7/8] 上传加密压缩包至冷存储 => ${RCLONE_REMOTE_REPO}..." + rclone_copy "${archive_file}" "${RCLONE_REMOTE_REPO}" + + # > 步骤 8: 控制副本数并清理本地 + log_message "INFO" "[Step 8/8] 控制冷备份的副本数量 => ${MAX_ENCRYPTED_REPLICAS}..." + rclone_control_replicas "${RCLONE_REMOTE_REPO}" "${APP_NAME}-backup-" "${MAX_ENCRYPTED_REPLICAS}" + cleanup_local_encrypted_files "${SCRIPT_RUN_DIR}" +# rm -rf "${LOCAL_BACKUP_DIR}" + + log_message "INFO" "====== ${APP_NAME} 备份任务已全部完成! ======" +} + +# ============================================================================= +# 脚本入口点 +# ============================================================================= +# 函数调用关系图 +# main +# ├─ toggle_maintenance_mode (2) +# │ └─ execute_remote_command +# ├─ execute_remote_command (2) +# ├─ encrypt_with_7zip +# ├─ rclone_copy +# ├─ rclone_control_replicas +# └─ cleanup_local_encrypted_files +# ============================================================================= +main "$@" diff --git a/0-部署应用/CloudCone-备份中心/vault-warden-backup.sh b/0-部署应用/CloudCone-备份中心/vault-warden-backup.sh new file mode 100644 index 0000000..154b8b6 --- /dev/null +++ b/0-部署应用/CloudCone-备份中心/vault-warden-backup.sh @@ -0,0 +1,85 @@ +#!/usr/bin/env bash +# ============================================================================= +# Meta : Vault-Warden 备份执行脚本 +# Version : 2.0.0 +# Author : Bash Shell Senior Development Engineer +# License : MIT +# Description : 自动化执行Vaultwarden远程备份、同步、加密、上传及清理任务。 +# ============================================================================= + +# > 导入公共库 +source "$(dirname "$0")/common.sh" || { echo "FATAL: common.sh not found." >&2; exit 1; } + +#------------------------------------------------------------------------------ +# 脚本配置区 +#------------------------------------------------------------------------------ +readonly APP_NAME="VaultWarden" +readonly REMOTE_USER="root" +readonly REMOTE_HOST="s5" +readonly MAX_ENCRYPTED_REPLICAS=5 # 远程保留的最大加密副本数 + +# > 远程路径 +readonly REMOTE_BACKUP_CMD="docker exec vault-warden /vaultwarden backup" +readonly REMOTE_DATA_DIR="/data/vault-warden/persist-data" +readonly REMOTE_DB_BACKUP_GLOB="${REMOTE_DATA_DIR}/db_*.sqlite3" + +# > 本地路径 +readonly LOCAL_BACKUP_DIR="/data/s5_146-56-159-175/vault-warden" + +# ============================================================================= +# 主执行流程 +# ============================================================================= +main() { + trap 'log_message "ERROR" "${APP_NAME}的备份任务出现错误! 终止"' ERR + log_message "INFO" "====== 开始 ${APP_NAME} 备份任务 ======" + + # > 步骤 1: 远程执行官方备份命令 + log_message "INFO" "[Step 1/7] 远程执行官方备份命令..." + execute_remote_command "${REMOTE_USER}" "${REMOTE_HOST}" "${REMOTE_BACKUP_CMD}" + + # > 步骤 2: rsync复制备份文件到本地 + log_message "INFO" "[Step 2/7] rsync复制备份文件到本地..." + mkdir -p "${LOCAL_BACKUP_DIR}" + rsync -avz --progress -e "ssh -p ${REMOTE_SSH_PORT}" \ + "${REMOTE_USER}@${REMOTE_HOST}:${REMOTE_DATA_DIR}/" \ + "${LOCAL_BACKUP_DIR}/" --include='db_*.sqlite3' --include='config.json' --include='rsa_key*' --include='attachments/***' --include='icon_cache/***' --include='sends/***' --exclude='*' + + # > 步骤 3: 远程清理备份的数据库文件 + log_message "INFO" "[Step 3/7] 远程清理备份的数据库文件..." + execute_remote_command "${REMOTE_USER}" "${REMOTE_HOST}" "rm -f ${REMOTE_DB_BACKUP_GLOB}" + + # > 步骤 4: 7zip加密本地目录 + local archive_file="${SCRIPT_RUN_DIR}/${APP_NAME}-backup-$(date +%Y%m%d-%H%M%S).7z" + log_message "INFO" "[Step 4/7] 7zip加密本地目录..." + 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}/db_*.sqlite3" + + + log_message "INFO" "====== ${APP_NAME} 备份任务已全部完成! ======" +} + +# ============================================================================= +# 脚本入口点 +# ============================================================================= +# 函数调用关系图 +# main +# ├─ execute_remote_command (2) +# ├─ encrypt_with_7zip +# ├─ rclone_copy +# ├─ rclone_control_replicas +# └─ cleanup_local_encrypted_files +# ============================================================================= +main "$@" diff --git a/0-部署应用/CloudCone-备份中心/备份说明.md b/0-部署应用/CloudCone-备份中心/备份说明.md deleted file mode 100644 index 12cdd3c..0000000 --- a/0-部署应用/CloudCone-备份中心/备份说明.md +++ /dev/null @@ -1,39 +0,0 @@ - - -# Vault-Warden备份 - -## 备份说明 -备份频率 每天一次 通过crontab执行 每天凌晨2点执行 -备份副本数 最近3份 -官方备份说明 https://github.com/dani-garcia/vaultwarden/wiki/Backing-up-your-vault - -## 备份过程 -1. 远程执行s5:执行vault-warden官方备份命令 -2. rsync复制s5主机上,特定的备份文件到本地主机备份目录/data/s5_146-56-159-175/vault-warden/ -3. 远程执行s5:删除掉备份的数据库文件 - - -# NextCloud备份 -## 备份说明 -备份频率 每周一次 通过crontab执行 每周日凌晨2点执行 -备份副本数 最近1份 -官方备份说明 https://docs.nextcloud.com/server/latest/admin_manual/maintenance/backup.html - -## 备份过程 -1. 远程执行s5:启用维护模式 docker exec nextcloud_web php occ maintenance:mode --on -2. 远程执行s5:数据库备份 (MariaDB) docker exec nextcloud-db mariadb-dump --single-transaction -h localhost -u nextcloud -p'boge14@Level5' nextcloud > /data/nextcloud/nextcloud-db_backup_$(date +%Y%m%d-%H%M%S).sql -3. rsync复制s5主机上下面的备份文件,到本地主机目录/data/s5_146-56-159-175/nextcloud/ - 1. /data/nextcloud/* -4. 远程执行s5: 删除掉下面的文件 - 1. /data/nextcloud/nextcloud-db_backup_*.sql -5. 远程执行s5: 禁用维护模式 docker exec nextcloud_web php occ maintenance:mode --off - - -# Gitea备份 -## 备份说明 -备份频率 每周三 周六凌晨2点执行 -备份副本数 最近3份 -官方备份说明 https://docs.gitea.com/zh-tw/administration/backup-and-restore - -## 备份过程 -1. 远程执行t0: 执行gitea备份命令 docker exec -it --tempdir=/bitnami/gitea/tmp gitea-gitea-1 /opt/bitnami/gitea/bin/gitea dump -c /bitnami/gitea/custom/conf/app.ini \ No newline at end of file diff --git a/0-部署应用/CloudCone-备份中心/基本环境说明.txt b/0-部署应用/CloudCone-备份中心/设计稿/基本环境说明.txt similarity index 100% rename from 0-部署应用/CloudCone-备份中心/基本环境说明.txt rename to 0-部署应用/CloudCone-备份中心/设计稿/基本环境说明.txt diff --git a/0-部署应用/CloudCone-备份中心/备份内容说明.txt b/0-部署应用/CloudCone-备份中心/设计稿/备份内容说明.txt similarity index 100% rename from 0-部署应用/CloudCone-备份中心/备份内容说明.txt rename to 0-部署应用/CloudCone-备份中心/设计稿/备份内容说明.txt diff --git a/0-部署应用/CloudCone-备份中心/设计稿/备份说明.md b/0-部署应用/CloudCone-备份中心/设计稿/备份说明.md new file mode 100644 index 0000000..9375093 --- /dev/null +++ b/0-部署应用/CloudCone-备份中心/设计稿/备份说明.md @@ -0,0 +1,108 @@ + +# 异地冷备份 +## Rclone的方式 +- 备份到GoogleDrive里面 + + +抽取三个脚本中复用的函数及变量到公共的sh文件中 +- 已知公共变量 + 1. 脚本运行目录为 /root/wdd/backup + 2. 脚本运行日志目录为 /root/wdd/backup/logs + 3. 远程主机的ssh端口均为22333 + 4. 默认日志级别 + 5. 7zip加密密码 + 6. rclone远程仓库地址 +- 已知公共函数 + 1. 日志函数 + 1. 不同日志级别 + 2. INFO以上级别日志需要打印至文件中 + 2. 远程执行函数 + 1. 在远程主机执行命令 + 2. ssh端口缺省值为22 + 3. 7zip加密函数-将特定的备份目录,全部加密压缩为压缩包 + 4. rclone复制函数 + 1. 将本地的加密压缩包,上传到远端 rclone copy xxx.7z gd-zeaslity:CloneCone-BackUp + 5. rclone远程仓库副本数控制函数 + 1. rclone检测google drive种压缩包的数量,根据xxx_max_encrpted_replicas进行限制,控制最大压缩包数量,按照时间排序删除最早的压缩包 + 6. 本地加密压缩包清理函数 + 1. 删除特定目录下的 ***.7z压缩包 + +# Vault-Warden备份 + +## 备份说明 +备份频率 每天一次 通过crontab执行 每天凌晨2点执行 +备份副本数 最近3份 +官方备份说明 https://github.com/dani-garcia/vaultwarden/wiki/Backing-up-your-vault + +## 备份过程 +1. 远程执行s5:执行vault-warden官方备份命令 +2. rsync复制s5主机上,特定的备份文件到本地主机备份目录/data/s5_146-56-159-175/vault-warden/ +3. 远程执行s5:删除掉备份的数据库文件 +4. 7zip加密函数 压缩本地目录 +5. rclone复制函数 上传压缩包 +6. rclone远程仓库副本数控制函数 根据vault-warden_max_encrpted_replicas控制远程的副本数量 +7. 本地加密压缩包清理函数 + +# NextCloud备份 +## 备份说明 +备份频率 每周一次 通过crontab执行 每周日凌晨2点执行 +备份副本数 最近1份 +官方备份说明 https://docs.nextcloud.com/server/latest/admin_manual/maintenance/backup.html + +## 备份过程 +1. 远程执行s5:启用维护模式 docker exec nextcloud_web php occ maintenance:mode --on +2. 远程执行s5:数据库备份 (MariaDB) docker exec nextcloud-db mariadb-dump --single-transaction -h localhost -u nextcloud -p'boge14@Level5' nextcloud > /data/nextcloud/nextcloud-db_backup_$(date +%Y%m%d-%H%M%S).sql +3. rsync复制s5主机上下面的备份文件,到本地主机目录/data/s5_146-56-159-175/nextcloud/ + 1. /data/nextcloud/* +4. 远程执行s5: 删除掉下面的文件 + 1. /data/nextcloud/nextcloud-db_backup_*.sql +5. 远程执行s5: 禁用维护模式 docker exec nextcloud_web php occ maintenance:mode --off +6. 7zip加密函数 压缩本地目录 +7. rclone复制函数 上传压缩包 +8. rclone远程仓库副本数控制函数 根据nextcloud_max_encrpted_replicas控制远程的副本数量 +9. 本地加密压缩包清理函数 + + +# Gitea备份 +## 备份说明 +备份频率 每周三 周六凌晨2点执行 /root/wdd/backup/gitea-backup.sh +备份副本数 最近3份 +官方备份说明 https://docs.gitea.com/zh-tw/administration/backup-and-restore + +## 备份过程 +1. 远程执行t0: 执行gitea备份命令 docker exec -it gitea-gitea-1 /opt/bitnami/gitea/bin/gitea dump -c /bitnami/gitea/custom/conf/app.ini +2. 远程执行t0: 执行 docker exec -it gitea-gitea-1 /bin/sh -c "mv /opt/bitnami/gitea/gitea-dump-*.zip /opt/bitnami/gitea/data/tmp/gitea-dump-$(date +%Y%m%d-%H%M%S).zip" +3. rsync复制t0主机上的 /data/gitea/gitea_data/data/tmp/gitea-dump-*.zip ,到本地主机目录/data/t0_150_230_198_103/gitea/ +4. 远程执行t0: 清除本地备份 rm /data/gitea/gitea_data/data/tmp/gitea-dump-*.zip +5. 7zip加密函数 压缩本地目录 +6. rclone复制函数 上传压缩包 +7. rclone远程仓库副本数控制函数 根据gitea_max_encrpted_replicas控制远程的副本数量 +8. 本地加密压缩包清理函数 + +请在ubnutu环境下使用定时任务,按照定时频率执行如下的任务 +每周三 周六凌晨2点执行 /root/wdd/backup/gitea-backup.sh +每周日凌晨2点执行 /root/wdd/backup/nextcloud-backup.sh +每天凌晨2点执行 /root/wdd/backup/vault-warden-backup.sh +要求脚本的执行目录为 /root/wdd/backup +请给出crontab的命令 请给出查看定时任务执行日志的命令 + + +# 添加以下内容: +# Gitea备份 - 每周三、周六凌晨2点 +0 2 * * 3,6 cd /root/wdd/backup && /root/wdd/backup/gitea-backup.sh +# Nextcloud备份 - 每周日凌晨2点 +0 2 * * 0 cd /root/wdd/backup && /root/wdd/backup/nextcloud-backup.sh +# Vaultwarden备份 - 每天凌晨2点 +0 2 * * * cd /root/wdd/backup && /root/wdd/backup/vault-warden-backup.sh + + +查看cron服务的系统日志(推荐方式) +sudo grep CRON /var/log/syslog +# 或者使用journalctl查看系统日志 +sudo journalctl -u cron.service --since today +# 查看特定备份脚本的执行日志(需要脚本内有日志输出) +sudo tail -f /var/log/syslog | grep -E "(gitea-backup|nextcloud-backup|vault-warden-backup)" +# 查看最近24小时的cron执行记录 +sudo grep CRON /var/log/syslog | grep "$(date +'%b %e')" +# 查看特定日期的执行记录(例如查看10月15日的记录) +sudo grep CRON /var/log/syslog | grep "Oct 15" \ No newline at end of file diff --git a/0-部署应用/CloudCone-备份中心/服务器数据备份与恢复方案.docx b/0-部署应用/CloudCone-备份中心/设计稿/服务器数据备份与恢复方案.docx similarity index 100% rename from 0-部署应用/CloudCone-备份中心/服务器数据备份与恢复方案.docx rename to 0-部署应用/CloudCone-备份中心/设计稿/服务器数据备份与恢复方案.docx diff --git a/0-部署应用/Tokyo-arm64-01/自建代码仓库-gitea/gitea-bitnami-docker-compose.yaml b/0-部署应用/Tokyo-arm64-01/自建代码仓库-gitea/gitea-bitnami-docker-compose.yaml index 89d76e9..f158e87 100644 --- a/0-部署应用/Tokyo-arm64-01/自建代码仓库-gitea/gitea-bitnami-docker-compose.yaml +++ b/0-部署应用/Tokyo-arm64-01/自建代码仓库-gitea/gitea-bitnami-docker-compose.yaml @@ -19,11 +19,11 @@ services: - GITEA_DATABASE_USERNAME=bn_gitea - GITEA_DATABASE_PASSWORD=Superwdd.12 - GITEA_ADMIN_USER=zeaslity - - GITEA_ADMIN_PASSWORD=lovemm.23 + - GITEA_ADMIN_PASSWORD=loveff.cxc.23 - GITEA_ADMIN_EMAIL=wdd@107421.xyz - GITEA_HTTP_PORT=3000 # - GITEA_DOMAIN=gitea.107421.xyz -# - GITEA_ROOT_URL=gitea.107421.xyz + - GITEA_ROOT_URL=https://gitea.107421.xyz - GITEA_SSH_LISTEN_PORT=22222 - ARCHIVE_CLEANUP_ENABLED = true - ARCHIVE_CLEANUP_TIMEOUT = 168h #设置归档文件过期时间(默认7天) diff --git a/2-NGINX相关/107421.xyz/21-申请证书.sh b/2-NGINX相关/107421.xyz/21-申请证书.sh index cd0aa89..3a28fb1 100644 --- a/2-NGINX相关/107421.xyz/21-申请证书.sh +++ b/2-NGINX相关/107421.xyz/21-申请证书.sh @@ -30,6 +30,9 @@ export DOMAIN_NAME=xx.p2.vl.s4.107421.xyz # BitsFlow-USA-LosAngles-CN2GIA export DOMAIN_NAME=xx.l4.ca.bg.107421.xyz +# seoul-arm-01 +export DOMAIN_NAME=office.107421.xyz + export CF_Token="y-OqT1Gan37vBUC1YaedmkKbsH6Kf84RH6Ve2b5x" export CF_Account_ID="dfaadeb83406ef5ad35da02617af9191" export CF_Zone_ID="511894a4f1357feb905e974e16241ebb" diff --git a/4-初始化/a-所有主机IP-host.txt b/4-初始化/a-所有主机IP-host.txt new file mode 100644 index 0000000..dfdd9ba --- /dev/null +++ b/4-初始化/a-所有主机IP-host.txt @@ -0,0 +1,57 @@ +127.0.0.1 localhost +127.0.0.1 $(hostname) + +# The following lines are desirable for IPv6 capable hosts +::1 ip6-localhost ip6-loopback +fe00::0 ip6-localnet +ff00::0 ip6-mcastprefix +ff02::1 ip6-allnodes +ff02::2 ip6-allrouters + +132.145.87.10 arm-s-1 s0 +10.0.0.91 arm-s-1 s0 + +146.56.159.175 arm-s-2 s5 +10.0.0.173 arm-s-2 s5 + +140.238.8.73 seoul-1 s1 +10.0.0.3 seoul-1 s1 + +140.238.30.110 seoul-2 s2 +10.0.0.14 seoul-2 s2 + +140.238.29.102 seoul-3 s3 +10.0.0.2 seoul-3 s3 + +140.238.14.103 seoul-4 s4 +10.0.0.3 seoul-4 s4 + +150.230.198.103 tokyo-0 t0 + +140.238.63.37 tokyo-1 t1 + +140.238.52.228 tokyo-2 t2 + +140.83.84.142 osaka-1 o1 + +140.83.58.96 osaka-2 o2 + +129.146.249.37 p1 + +129.146.171.163 p2 + +129.146.65.80 p3 arm-p-1 + +129.146.57.94 p4 arm-p-2 + +42.192.52.227 tc-sh + +43.128.39.232 tc-hk + +114.117.165.222 tc-cd + +154.40.34.106 los-1 bits cn2-1 + +45.134.50.233 de-1 rare + +64.69.32.106 cc-1 los-2 \ No newline at end of file diff --git a/0-部署应用/Oracle-Cloud/所有集群的IP网段-host.txt b/4-初始化/a-所有集群的IP网段-host.txt similarity index 100% rename from 0-部署应用/Oracle-Cloud/所有集群的IP网段-host.txt rename to 4-初始化/a-所有集群的IP网段-host.txt diff --git a/4-初始化/b-wdd-super-agent-初始化.sh b/4-初始化/b-wdd-super-agent-初始化.sh new file mode 100644 index 0000000..4282be3 --- /dev/null +++ b/4-初始化/b-wdd-super-agent-初始化.sh @@ -0,0 +1,66 @@ +#!/bin/bash + +rm -f /usr/local/bin/agent-wdd +rm -f /usr/local/bin/test-shell.sh + +# 支持arm64 修改即可 2025年9月2日 +wget https://pan.107421.xyz/d/oracle-seoul-2/agent-wdd_linux_amd64 -O /usr/local/bin/agent-wdd + +chmod +x /usr/local/bin/agent-wdd + + +/usr/local/bin/agent-wdd info all +cat /usr/local/etc/wdd/agent-wdd-config.yaml + + +/usr/local/bin/agent-wdd base firewall + +/usr/local/bin/agent-wdd base ssh config +/usr/local/bin/agent-wdd base ssh key + +/usr/local/bin/agent-wdd proxy xray install +/usr/local/bin/agent-wdd proxy vmess 22443 + + +#bash /usr/local/bin/test-shell.sh + + +/usr/local/bin/agent-wdd info network +/usr/local/bin/agent-wdd info cpu +/usr/local/bin/agent-wdd info mem +/usr/local/bin/agent-wdd info swap +/usr/local/bin/agent-wdd info disks + +/usr/local/bin/agent-wdd base docker local + +/usr/local/bin/agent-wdd info os +/usr/local/bin/agent-wdd base docker online + +/usr/local/bin/agent-wdd info os + + +/usr/local/bin/agent-wdd zsh + +/usr/local/bin/agent-wdd base tools + +/usr/local/bin/agent-wdd base swap + +/usr/local/bin/agent-wdd base firewall + +/usr/local/bin/agent-wdd base selinux + +/usr/local/bin/agent-wdd base sysconfig + + +/usr/local/bin/agent-wdd download https://pan.107421.xyz/d/oracle-osaka-1/docker-amd64-20.10.15.tgz /root/wdd + +/usr/local/bin/agent-wdd proxy xray install + +/usr/local/bin/agent-wdd proxy vmess 22443 + + +wget https://pan.107421.xyz/d/oracle-seoul-2/test-shell.sh -qO /usr/local/bin/test-shell.sh + +chmod +x /usr/local/bin/test-shell.sh + + diff --git a/4-初始化/snap-完全移除.sh b/4-初始化/snap-完全移除.sh index c6e166d..e57a075 100644 --- a/4-初始化/snap-完全移除.sh +++ b/4-初始化/snap-完全移除.sh @@ -23,6 +23,7 @@ rm -rf /var/snap/ rm -rf /var/lib/snapd/ rm -rf /snap/ rm -rf ~/.snap/ +rm -rf /root/snap/ # 更新软件包列表 apt update diff --git a/脚本参考/XA工作理解.txt b/脚本参考/XA工作理解.txt deleted file mode 100644 index 3ffc227..0000000 --- a/脚本参考/XA工作理解.txt +++ /dev/null @@ -1,10 +0,0 @@ -剑哥你好,关于雄安交流的工作,我做了一定的工作和理解 - -背景是:雄安政策对于低空经济的支持还是相当大的,详见PPT;已经有竞品公司,中国电信成立团队,中国邮政的无人机快递,中国通号的低空监视防护网等各家公司的进驻; - -关于工作的理解和安排,总结如下: -1. 低空经济政策顶规:我已请教何博,对于相关的工作内容有了一定的了解。 -2. 市场扩展:雄安移动的资源力度,能否考虑构建北方的示范基地 -3. 工作及个人安排:可以外驻交流,脱离目前工作的“舒适圈”。主体工作交由技术支撑交付团队完成 - -还望剑哥批评指正,一切服从组织安排。 \ No newline at end of file