110 lines
3.7 KiB
Bash
110 lines
3.7 KiB
Bash
|
|
#!/bin/bash
|
||
|
|
# =============================================================================
|
||
|
|
# LetsBe Backup Script
|
||
|
|
# =============================================================================
|
||
|
|
# Backs up Docker volumes and databases to configured rclone remote
|
||
|
|
# Configure rclone first: rclone config
|
||
|
|
# =============================================================================
|
||
|
|
|
||
|
|
set -euo pipefail
|
||
|
|
|
||
|
|
BACKUP_DIR="/tmp/letsbe-backups"
|
||
|
|
DATE=$(date +%Y%m%d_%H%M%S)
|
||
|
|
RCLONE_REMOTE="remote" # Configure this in rclone config
|
||
|
|
|
||
|
|
# Create backup directory
|
||
|
|
mkdir -p "$BACKUP_DIR"
|
||
|
|
|
||
|
|
echo "=== LetsBe Backup - $DATE ==="
|
||
|
|
|
||
|
|
# Function to backup a postgres database
|
||
|
|
backup_postgres() {
|
||
|
|
local container=$1
|
||
|
|
local db_name=$2
|
||
|
|
local db_user=${3:-postgres}
|
||
|
|
|
||
|
|
if docker ps --format '{{.Names}}' | grep -q "^${container}$"; then
|
||
|
|
echo "Backing up PostgreSQL: $container ($db_name)..."
|
||
|
|
docker exec "$container" pg_dump -U "$db_user" "$db_name" | gzip > "$BACKUP_DIR/${container}_${DATE}.sql.gz"
|
||
|
|
fi
|
||
|
|
}
|
||
|
|
|
||
|
|
# Function to backup a mysql database
|
||
|
|
backup_mysql() {
|
||
|
|
local container=$1
|
||
|
|
local db_name=$2
|
||
|
|
local db_user=${3:-root}
|
||
|
|
local db_pass=$4
|
||
|
|
|
||
|
|
if docker ps --format '{{.Names}}' | grep -q "^${container}$"; then
|
||
|
|
echo "Backing up MySQL: $container ($db_name)..."
|
||
|
|
docker exec "$container" mysqldump -u"$db_user" -p"$db_pass" "$db_name" | gzip > "$BACKUP_DIR/${container}_${DATE}.sql.gz"
|
||
|
|
fi
|
||
|
|
}
|
||
|
|
|
||
|
|
# Function to backup docker volumes
|
||
|
|
backup_volume() {
|
||
|
|
local volume=$1
|
||
|
|
|
||
|
|
if docker volume ls --format '{{.Name}}' | grep -q "^${volume}$"; then
|
||
|
|
echo "Backing up volume: $volume..."
|
||
|
|
docker run --rm -v "${volume}:/data" -v "$BACKUP_DIR:/backup" alpine tar czf "/backup/${volume}_${DATE}.tar.gz" -C /data .
|
||
|
|
fi
|
||
|
|
}
|
||
|
|
|
||
|
|
# =============================================================================
|
||
|
|
# BACKUP DATABASES
|
||
|
|
# =============================================================================
|
||
|
|
|
||
|
|
# Chatwoot
|
||
|
|
backup_postgres "*-chatwoot-postgres" "chatwoot_production" "chatwoot" 2>/dev/null || true
|
||
|
|
|
||
|
|
# NoCoDB
|
||
|
|
backup_postgres "*-nocodb-postgres" "nocodb" "postgres" 2>/dev/null || true
|
||
|
|
|
||
|
|
# Baserow
|
||
|
|
backup_postgres "*-baserow-db" "baserow" "baserow" 2>/dev/null || true
|
||
|
|
|
||
|
|
# n8n
|
||
|
|
backup_postgres "*-n8n-postgres" "n8n" "n8n" 2>/dev/null || true
|
||
|
|
|
||
|
|
# Nextcloud
|
||
|
|
backup_postgres "*-nextcloud-postgres" "nextcloud" "nextcloud" 2>/dev/null || true
|
||
|
|
|
||
|
|
# Typebot
|
||
|
|
backup_postgres "*-typebot-db" "typebot" "postgres" 2>/dev/null || true
|
||
|
|
|
||
|
|
# =============================================================================
|
||
|
|
# BACKUP VOLUMES (important data)
|
||
|
|
# =============================================================================
|
||
|
|
|
||
|
|
# Get all letsbe-related volumes
|
||
|
|
for vol in $(docker volume ls --format '{{.Name}}' | grep -E '(storage|data|uploads)'); do
|
||
|
|
backup_volume "$vol" 2>/dev/null || true
|
||
|
|
done
|
||
|
|
|
||
|
|
# =============================================================================
|
||
|
|
# UPLOAD TO REMOTE
|
||
|
|
# =============================================================================
|
||
|
|
|
||
|
|
if command -v rclone &> /dev/null; then
|
||
|
|
if rclone listremotes | grep -q "^${RCLONE_REMOTE}:"; then
|
||
|
|
echo "Uploading backups to $RCLONE_REMOTE..."
|
||
|
|
rclone copy "$BACKUP_DIR" "${RCLONE_REMOTE}:letsbe-backups/${DATE}/" --progress
|
||
|
|
echo "Upload complete."
|
||
|
|
else
|
||
|
|
echo "WARNING: rclone remote '$RCLONE_REMOTE' not configured. Backups stored locally only."
|
||
|
|
fi
|
||
|
|
else
|
||
|
|
echo "WARNING: rclone not installed. Backups stored locally only."
|
||
|
|
fi
|
||
|
|
|
||
|
|
# =============================================================================
|
||
|
|
# CLEANUP OLD LOCAL BACKUPS (keep last 7 days)
|
||
|
|
# =============================================================================
|
||
|
|
|
||
|
|
find "$BACKUP_DIR" -type f -mtime +7 -delete 2>/dev/null || true
|
||
|
|
|
||
|
|
echo "=== Backup Complete ==="
|
||
|
|
echo "Local backups: $BACKUP_DIR"
|