完成CloudCone备份服务器的设置

This commit is contained in:
zeaslity
2025-09-03 14:14:19 +08:00
parent b5e802ebc3
commit 9d93a1ee6e
20 changed files with 1434 additions and 98 deletions

View File

@@ -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/

View File

@@ -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 <string> 日志级别 (DEBUG/INFO/WARN/ERROR)
# @param message <string> 要记录的日志消息
# @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 <string> 远程主机用户名
# @param remote_host <string> 远程主机名或IP地址
# @param remote_command <string> 待执行的命令
# @param ssh_port <string> SSH端口 (可选, 默认22333)
# @return <exit_code> 远程命令的退出码
# @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 <string> 需要压缩的源目录路径
# @param archive_path <string> 生成的加密压缩包完整路径
# @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 <string> 本地源文件路径
# @param remote_destination <string> 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 <string> 远程仓库中的目录路径
# @param file_prefix <string> 需要管理副本数量的文件名前缀
# @param max_replicas <integer> 允许保留的最大副本数量
# @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 <string> 需要清理的目录路径
# @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
}

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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 "$@"

View File

@@ -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 <string> 模式, '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 "$@"

View File

@@ -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 "$@"

View File

@@ -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

View File

@@ -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"

View File

@@ -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天

View File

@@ -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"

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -1,10 +0,0 @@
剑哥你好,关于雄安交流的工作,我做了一定的工作和理解
背景是雄安政策对于低空经济的支持还是相当大的详见PPT已经有竞品公司中国电信成立团队中国邮政的无人机快递中国通号的低空监视防护网等各家公司的进驻
关于工作的理解和安排,总结如下:
1. 低空经济政策顶规:我已请教何博,对于相关的工作内容有了一定的了解。
2. 市场扩展:雄安移动的资源力度,能否考虑构建北方的示范基地
3. 工作及个人安排:可以外驻交流,脱离目前工作的“舒适圈”。主体工作交由技术支撑交付团队完成
还望剑哥批评指正,一切服从组织安排。