backup_trilium_to_cst.sh

#!/usr/bin/env bash

set -uo pipefail

# ===== 配置 =====
APP_DIR="/opt/1panel/apps/trilium/trilium"
SRC_DIR="$APP_DIR/data"

S3_DIR="/mnt/cst/backups/trilium"
TMP_DIR="/tmp"
KEEP=7

PASSFILE="$HOME/.backup_pass"
PASSPHRASE=$(cat "$PASSFILE")

DATE=$(date +"%Y-%m-%d_%H-%M-%S")
ARCHIVE="$TMP_DIR/trilium_backup_$DATE.tar.gz"
ENCRYPTED="$ARCHIVE.gpg"
LOG="$HOME/backup.log"

echo "[$(date)] Backup start" >> "$LOG"

# ===== 停止容器 =====
docker compose -f "$APP_DIR/docker-compose.yml" stop || true

# ===== 确保退出时启动 =====
force_start_container() {
    docker compose -f "$APP_DIR/docker-compose.yml" start || true
}
trap force_start_container EXIT

# ===== 创建目录 =====
mkdir -p "$S3_DIR"

cd "$APP_DIR"
# ===== 打包 =====
if ! tar -czf "$ARCHIVE" --exclude="tmp" --exclude="log" "$SRC_DIR"; then
    echo "[$(date)] Warning: tar failed" >> "$LOG"
fi

# ===== 加密 =====
if ! gpg --batch --yes \
    --passphrase "$PASSPHRASE" \
    --symmetric --cipher-algo AES256 \
    -o "$ENCRYPTED" "$ARCHIVE"; then
    echo "[$(date)] Warning: gpg failed" >> "$LOG"
fi

# ===== 上传 =====
if ! cp "$ENCRYPTED" "$S3_DIR/"; then
    echo "[$(date)] Warning: cp error (FUSE)" >> "$LOG"
fi

# ===== 删除临时文件 =====
rm -f "$ARCHIVE" "$ENCRYPTED"

# ===== 清理旧备份 =====
cd "$S3_DIR"
ls -t trilium_backup_*.tar.gz.gpg 2>/dev/null | tail -n +$((KEEP+1)) | xargs -r rm

echo "[$(date)] Backup finished" >> "$LOG"