v0.3.0 - Complete deployment documentation and examples - Added comprehensive deployment guide, automated deployment scripts, nginx SSL proxy setup, backup automation, and monitoring tools. Includes VPS deployment, cloud platform guides, and practical examples for production deployment of event-based configuration system.
This commit is contained in:
367
examples/deployment/backup/backup-relay.sh
Executable file
367
examples/deployment/backup/backup-relay.sh
Executable file
@@ -0,0 +1,367 @@
|
||||
#!/bin/bash
|
||||
|
||||
# C Nostr Relay - Backup Script
|
||||
# Automated backup solution for event-based configuration relay
|
||||
|
||||
set -e
|
||||
|
||||
# Colors for output
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
# Default configuration
|
||||
RELAY_DIR="/opt/c-relay"
|
||||
BACKUP_DIR="/backup/c-relay"
|
||||
RETENTION_DAYS="30"
|
||||
COMPRESS="true"
|
||||
REMOTE_BACKUP=""
|
||||
S3_BUCKET=""
|
||||
NOTIFICATION_EMAIL=""
|
||||
LOG_FILE="/var/log/relay-backup.log"
|
||||
|
||||
# Functions
|
||||
print_step() {
|
||||
echo -e "${BLUE}[STEP]${NC} $1"
|
||||
echo "$(date '+%Y-%m-%d %H:%M:%S') [STEP] $1" >> "$LOG_FILE"
|
||||
}
|
||||
|
||||
print_success() {
|
||||
echo -e "${GREEN}[SUCCESS]${NC} $1"
|
||||
echo "$(date '+%Y-%m-%d %H:%M:%S') [SUCCESS] $1" >> "$LOG_FILE"
|
||||
}
|
||||
|
||||
print_warning() {
|
||||
echo -e "${YELLOW}[WARNING]${NC} $1"
|
||||
echo "$(date '+%Y-%m-%d %H:%M:%S') [WARNING] $1" >> "$LOG_FILE"
|
||||
}
|
||||
|
||||
print_error() {
|
||||
echo -e "${RED}[ERROR]${NC} $1"
|
||||
echo "$(date '+%Y-%m-%d %H:%M:%S') [ERROR] $1" >> "$LOG_FILE"
|
||||
}
|
||||
|
||||
show_help() {
|
||||
echo "Usage: $0 [OPTIONS]"
|
||||
echo
|
||||
echo "Options:"
|
||||
echo " -d, --relay-dir DIR Relay directory (default: /opt/c-relay)"
|
||||
echo " -b, --backup-dir DIR Backup directory (default: /backup/c-relay)"
|
||||
echo " -r, --retention DAYS Retention period in days (default: 30)"
|
||||
echo " -n, --no-compress Don't compress backups"
|
||||
echo " -s, --s3-bucket BUCKET Upload to S3 bucket"
|
||||
echo " -e, --email EMAIL Send notification email"
|
||||
echo " -v, --verify Verify backup integrity"
|
||||
echo " -h, --help Show this help message"
|
||||
echo
|
||||
echo "Examples:"
|
||||
echo " $0 # Basic backup"
|
||||
echo " $0 -s my-backup-bucket -e admin@example.com"
|
||||
echo " $0 -r 7 -n # 7-day retention, no compression"
|
||||
}
|
||||
|
||||
parse_args() {
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case $1 in
|
||||
-d|--relay-dir)
|
||||
RELAY_DIR="$2"
|
||||
shift 2
|
||||
;;
|
||||
-b|--backup-dir)
|
||||
BACKUP_DIR="$2"
|
||||
shift 2
|
||||
;;
|
||||
-r|--retention)
|
||||
RETENTION_DAYS="$2"
|
||||
shift 2
|
||||
;;
|
||||
-n|--no-compress)
|
||||
COMPRESS="false"
|
||||
shift
|
||||
;;
|
||||
-s|--s3-bucket)
|
||||
S3_BUCKET="$2"
|
||||
shift 2
|
||||
;;
|
||||
-e|--email)
|
||||
NOTIFICATION_EMAIL="$2"
|
||||
shift 2
|
||||
;;
|
||||
-v|--verify)
|
||||
VERIFY="true"
|
||||
shift
|
||||
;;
|
||||
-h|--help)
|
||||
show_help
|
||||
exit 0
|
||||
;;
|
||||
*)
|
||||
print_error "Unknown option: $1"
|
||||
show_help
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
}
|
||||
|
||||
check_dependencies() {
|
||||
print_step "Checking dependencies..."
|
||||
|
||||
# Check sqlite3
|
||||
if ! command -v sqlite3 &> /dev/null; then
|
||||
print_error "sqlite3 not found. Install with: apt install sqlite3"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check compression tools
|
||||
if [[ "$COMPRESS" == "true" ]]; then
|
||||
if ! command -v gzip &> /dev/null; then
|
||||
print_error "gzip not found for compression"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
# Check S3 tools if needed
|
||||
if [[ -n "$S3_BUCKET" ]]; then
|
||||
if ! command -v aws &> /dev/null; then
|
||||
print_error "AWS CLI not found. Install with: apt install awscli"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
print_success "Dependencies verified"
|
||||
}
|
||||
|
||||
find_database() {
|
||||
print_step "Finding relay database..."
|
||||
|
||||
# Look for .nrdb files in relay directory
|
||||
DB_FILES=($(find "$RELAY_DIR" -name "*.nrdb" 2>/dev/null))
|
||||
|
||||
if [[ ${#DB_FILES[@]} -eq 0 ]]; then
|
||||
print_error "No relay database files found in $RELAY_DIR"
|
||||
exit 1
|
||||
elif [[ ${#DB_FILES[@]} -gt 1 ]]; then
|
||||
print_warning "Multiple database files found:"
|
||||
printf '%s\n' "${DB_FILES[@]}"
|
||||
print_warning "Using the first one: ${DB_FILES[0]}"
|
||||
fi
|
||||
|
||||
DB_FILE="${DB_FILES[0]}"
|
||||
DB_NAME=$(basename "$DB_FILE")
|
||||
|
||||
print_success "Found database: $DB_FILE"
|
||||
}
|
||||
|
||||
create_backup_directory() {
|
||||
print_step "Creating backup directory..."
|
||||
|
||||
if [[ ! -d "$BACKUP_DIR" ]]; then
|
||||
mkdir -p "$BACKUP_DIR"
|
||||
chmod 700 "$BACKUP_DIR"
|
||||
print_success "Created backup directory: $BACKUP_DIR"
|
||||
else
|
||||
print_success "Using existing backup directory: $BACKUP_DIR"
|
||||
fi
|
||||
}
|
||||
|
||||
perform_backup() {
|
||||
local timestamp=$(date +%Y%m%d_%H%M%S)
|
||||
local backup_name="relay_backup_${timestamp}"
|
||||
local backup_file="$BACKUP_DIR/${backup_name}.nrdb"
|
||||
|
||||
print_step "Creating database backup..."
|
||||
|
||||
# Check if database is accessible
|
||||
if [[ ! -r "$DB_FILE" ]]; then
|
||||
print_error "Cannot read database file: $DB_FILE"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Get database size
|
||||
local db_size=$(du -h "$DB_FILE" | cut -f1)
|
||||
print_step "Database size: $db_size"
|
||||
|
||||
# Create SQLite backup using .backup command (hot backup)
|
||||
if sqlite3 "$DB_FILE" ".backup $backup_file" 2>/dev/null; then
|
||||
print_success "Database backup created: $backup_file"
|
||||
else
|
||||
# Fallback to file copy if .backup fails
|
||||
print_warning "SQLite backup failed, using file copy method"
|
||||
cp "$DB_FILE" "$backup_file"
|
||||
print_success "File copy backup created: $backup_file"
|
||||
fi
|
||||
|
||||
# Verify backup file
|
||||
if [[ ! -f "$backup_file" ]]; then
|
||||
print_error "Backup file was not created"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check backup integrity
|
||||
if [[ "$VERIFY" == "true" ]]; then
|
||||
print_step "Verifying backup integrity..."
|
||||
if sqlite3 "$backup_file" "PRAGMA integrity_check;" | grep -q "ok"; then
|
||||
print_success "Backup integrity verified"
|
||||
else
|
||||
print_error "Backup integrity check failed"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
# Compress backup
|
||||
if [[ "$COMPRESS" == "true" ]]; then
|
||||
print_step "Compressing backup..."
|
||||
gzip "$backup_file"
|
||||
backup_file="${backup_file}.gz"
|
||||
print_success "Backup compressed: $backup_file"
|
||||
fi
|
||||
|
||||
# Set backup file as global variable for other functions
|
||||
BACKUP_FILE="$backup_file"
|
||||
BACKUP_NAME="$backup_name"
|
||||
}
|
||||
|
||||
upload_to_s3() {
|
||||
if [[ -z "$S3_BUCKET" ]]; then
|
||||
return 0
|
||||
fi
|
||||
|
||||
print_step "Uploading backup to S3..."
|
||||
|
||||
local s3_path="s3://$S3_BUCKET/c-relay/$(date +%Y)/$(date +%m)/"
|
||||
|
||||
if aws s3 cp "$BACKUP_FILE" "$s3_path" --storage-class STANDARD_IA; then
|
||||
print_success "Backup uploaded to S3: $s3_path"
|
||||
else
|
||||
print_error "Failed to upload backup to S3"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
cleanup_old_backups() {
|
||||
print_step "Cleaning up old backups..."
|
||||
|
||||
local deleted_count=0
|
||||
|
||||
# Clean local backups
|
||||
while IFS= read -r -d '' file; do
|
||||
rm "$file"
|
||||
((deleted_count++))
|
||||
done < <(find "$BACKUP_DIR" -name "relay_backup_*.nrdb*" -mtime "+$RETENTION_DAYS" -print0 2>/dev/null)
|
||||
|
||||
if [[ $deleted_count -gt 0 ]]; then
|
||||
print_success "Deleted $deleted_count old local backups"
|
||||
else
|
||||
print_success "No old local backups to delete"
|
||||
fi
|
||||
|
||||
# Clean S3 backups if configured
|
||||
if [[ -n "$S3_BUCKET" ]]; then
|
||||
local cutoff_date=$(date -d "$RETENTION_DAYS days ago" +%Y-%m-%d)
|
||||
print_step "Cleaning S3 backups older than $cutoff_date..."
|
||||
|
||||
# Note: This is a simplified approach. In production, use S3 lifecycle policies
|
||||
aws s3 ls "s3://$S3_BUCKET/c-relay/" --recursive | \
|
||||
awk '$1 < "'$cutoff_date'" {print $4}' | \
|
||||
while read -r key; do
|
||||
aws s3 rm "s3://$S3_BUCKET/$key"
|
||||
print_step "Deleted S3 backup: $key"
|
||||
done
|
||||
fi
|
||||
}
|
||||
|
||||
send_notification() {
|
||||
if [[ -z "$NOTIFICATION_EMAIL" ]]; then
|
||||
return 0
|
||||
fi
|
||||
|
||||
print_step "Sending notification email..."
|
||||
|
||||
local subject="C Nostr Relay Backup - $(date +%Y-%m-%d)"
|
||||
local backup_size=$(du -h "$BACKUP_FILE" | cut -f1)
|
||||
|
||||
local message="Backup completed successfully.
|
||||
|
||||
Details:
|
||||
- Date: $(date)
|
||||
- Database: $DB_FILE
|
||||
- Backup File: $BACKUP_FILE
|
||||
- Backup Size: $backup_size
|
||||
- Retention: $RETENTION_DAYS days
|
||||
"
|
||||
|
||||
if [[ -n "$S3_BUCKET" ]]; then
|
||||
message+="\n- S3 Bucket: $S3_BUCKET"
|
||||
fi
|
||||
|
||||
# Try to send email using mail command
|
||||
if command -v mail &> /dev/null; then
|
||||
echo -e "$message" | mail -s "$subject" "$NOTIFICATION_EMAIL"
|
||||
print_success "Notification sent to $NOTIFICATION_EMAIL"
|
||||
else
|
||||
print_warning "Mail command not available, skipping notification"
|
||||
fi
|
||||
}
|
||||
|
||||
show_backup_summary() {
|
||||
local backup_size=$(du -h "$BACKUP_FILE" | cut -f1)
|
||||
local backup_count=$(find "$BACKUP_DIR" -name "relay_backup_*.nrdb*" | wc -l)
|
||||
|
||||
echo
|
||||
echo "🎉 Backup Completed Successfully!"
|
||||
echo
|
||||
echo "Backup Details:"
|
||||
echo " Source DB: $DB_FILE"
|
||||
echo " Backup File: $BACKUP_FILE"
|
||||
echo " Backup Size: $backup_size"
|
||||
echo " Compressed: $COMPRESS"
|
||||
echo " Verified: ${VERIFY:-false}"
|
||||
echo
|
||||
echo "Storage:"
|
||||
echo " Local Backups: $backup_count files in $BACKUP_DIR"
|
||||
echo " Retention: $RETENTION_DAYS days"
|
||||
|
||||
if [[ -n "$S3_BUCKET" ]]; then
|
||||
echo " S3 Bucket: $S3_BUCKET"
|
||||
fi
|
||||
|
||||
echo
|
||||
echo "Management Commands:"
|
||||
echo " List backups: find $BACKUP_DIR -name 'relay_backup_*'"
|
||||
echo " Restore: See examples/deployment/backup/restore-relay.sh"
|
||||
echo
|
||||
}
|
||||
|
||||
# Main execution
|
||||
main() {
|
||||
echo
|
||||
echo "==============================================="
|
||||
echo "💾 C Nostr Relay - Database Backup"
|
||||
echo "==============================================="
|
||||
echo
|
||||
|
||||
# Initialize log file
|
||||
mkdir -p "$(dirname "$LOG_FILE")"
|
||||
touch "$LOG_FILE"
|
||||
|
||||
parse_args "$@"
|
||||
check_dependencies
|
||||
find_database
|
||||
create_backup_directory
|
||||
perform_backup
|
||||
upload_to_s3
|
||||
cleanup_old_backups
|
||||
send_notification
|
||||
show_backup_summary
|
||||
|
||||
print_success "Backup process completed successfully!"
|
||||
}
|
||||
|
||||
# Handle errors
|
||||
trap 'print_error "Backup failed at line $LINENO"' ERR
|
||||
|
||||
# Run main function
|
||||
main "$@"
|
||||
Reference in New Issue
Block a user