#!/usr/bin/env bash set -euo pipefail # ============================================ # Joplin Server 备份脚本 # 备份 PostgreSQL 数据库 + 配置文件 # ============================================ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" cd "$SCRIPT_DIR" # 加载配置 if [ -f .env ]; then sed -i 's/\r$//' .env set -a; source .env; set +a else echo "[ERROR] .env 文件不存在,请先运行 deploy.sh" >&2 exit 1 fi # ===== 配置 ===== JOPLIN_DB_DIR="${JOPLIN_DB_DIR:-/data/joplin/db}" BACKUP_BASE="${BACKUP_DIR:-/var/backups/joplin}" TIMESTAMP=$(date +%Y%m%d_%H%M%S) BACKUP_DIR_FULL="${BACKUP_BASE}/${TIMESTAMP}" RETENTION_DAYS=30 echo "========== Joplin Server 备份 ==========" echo "时间: $(date '+%Y-%m-%d %H:%M:%S')" echo "数据库目录: $JOPLIN_DB_DIR" echo "备份目录: $BACKUP_DIR_FULL" echo "" mkdir -p "$BACKUP_DIR_FULL" # ===== 备份 PostgreSQL 数据库(使用 pg_dump)===== echo "[1/3] 备份 PostgreSQL 数据库..." if docker compose ps --quiet joplin-db 2>/dev/null | grep -q .; then docker compose exec -T joplin-db pg_dump \ -U "${POSTGRES_USER:-joplin}" \ -d "${POSTGRES_DATABASE:-joplin}" \ --format=custom \ > "$BACKUP_DIR_FULL/joplin-db.dump" echo " ✓ 数据库已备份(pg_dump)" else echo " ⚠ PostgreSQL 容器未运行,尝试直接备份数据目录..." if [ -d "$JOPLIN_DB_DIR" ]; then tar czf "$BACKUP_DIR_FULL/joplin-db-files.tar.gz" -C "$(dirname "$JOPLIN_DB_DIR")" "$(basename "$JOPLIN_DB_DIR")" echo " ✓ 数据库目录已备份" else echo " ⚠ 数据库目录不存在: $JOPLIN_DB_DIR" fi fi # ===== 备份 docker-compose 和配置 ===== echo "[2/3] 备份部署配置..." tar czf "$BACKUP_DIR_FULL/joplin-config.tar.gz" \ -C "$SCRIPT_DIR" \ docker-compose.yml .env nginx/ 2>/dev/null || true echo " ✓ 配置已备份" # ===== 清理旧备份 ===== echo "[3/3] 清理 ${RETENTION_DAYS} 天前的旧备份..." find "$BACKUP_BASE" -maxdepth 1 -type d -mtime +${RETENTION_DAYS} -exec rm -rf {} \; 2>/dev/null || true echo " ✓ 旧备份已清理" # ===== 汇总 ===== echo "" echo "========== 备份完成 ==========" TOTAL_SIZE=$(du -sh "$BACKUP_DIR_FULL" | cut -f1) echo "备份位置: $BACKUP_DIR_FULL" echo "备份大小: $TOTAL_SIZE" echo "" echo "备份内容:" ls -lh "$BACKUP_DIR_FULL/" echo "" echo "恢复方法(数据库):" echo " docker compose exec -T joplin-db pg_restore -U ${POSTGRES_USER:-joplin} -d ${POSTGRES_DATABASE:-joplin} --clean < $BACKUP_DIR_FULL/joplin-db.dump" echo " cd $SCRIPT_DIR && docker compose restart"