Set up automated backup and disaster recovery for Nexus Repository Manager 3 with blob store migration
Intermediate
45 min
May 17, 202697 views
Ubuntu 24.04Debian 12AlmaLinux 9Rocky Linux 9
Configure comprehensive backup automation for Nexus Repository Manager 3 including blob store migration, disaster recovery procedures, and automated scheduling with systemd timers for production environments.
Prerequisites
Nexus Repository Manager 3 installed
Root or sudo access
At least 50GB free disk space for backups
GPG installed for encryption
What this solves
Nexus Repository Manager stores artifacts across multiple blob stores that require coordinated backup strategies. This tutorial sets up automated backup procedures that capture both the database and blob store data, implements blob store migration capabilities, and creates disaster recovery workflows with systemd timer automation.
Install backup prerequisites and dependencies
Update system packages
Start by updating your package manager to ensure you have the latest versions of required tools.
sudo apt update && sudo apt upgrade -y
sudo dnf update -y
Install backup utilities
Install required tools for backup compression, encryption, and remote storage synchronization.
Never use chmod 777. It gives every user on the system full access to your backup files. Instead, use specific ownership with chown and minimal permissions like 750 for directories containing sensitive data.
Configure GPG encryption for backups
Generate encryption keys for secure backup storage.
stop_nexus() {
log "Stopping Nexus Repository Manager"
sudo systemctl stop nexus
sleep 10
}
start_nexus() {
log "Starting Nexus Repository Manager"
sudo systemctl start nexus
# Wait for service to be ready
local retries=0
while ! curl -sf http://localhost:8081/service/rest/v1/status > /dev/null; do
if [ $retries -ge 30 ]; then
log "ERROR: Nexus failed to start within 5 minutes"
exit 1
fi
sleep 10
((retries++))
done
log "Nexus Repository Manager started successfully"
}
Database backup
backup_database() {
local backup_dir="$1"
log "Backing up OrientDB database"
if [ -d "$NEXUS_DATA_DIR/db" ]; then
tar -czf "$backup_dir/orientdb-$(date +%Y%m%d-%H%M%S).tar.gz" \
-C "$NEXUS_DATA_DIR" db/
log "Database backup completed"
else
log "WARNING: Database directory not found at $NEXUS_DATA_DIR/db"
fi
}
Blob store backup with migration support
backup_blob_stores() {
local backup_dir="$1"
log "Backing up blob stores"
local blob_backup_dir="$backup_dir/blob-stores"
mkdir -p "$blob_backup_dir"
if [ -d "$NEXUS_DATA_DIR/blobs" ]; then
# Create blob store manifest
find "$NEXUS_DATA_DIR/blobs" -type f -name "*.properties" > "$blob_backup_dir/blob-manifest.txt"
# Backup each blob store
for blob_store in "$NEXUS_DATA_DIR/blobs"/*; do
if [ -d "$blob_store" ]; then
local store_name=$(basename "$blob_store")
log "Backing up blob store: $store_name"
tar -czf "$blob_backup_dir/$store_name-$(date +%Y%m%d-%H%M%S).tar.gz" \
-C "$NEXUS_DATA_DIR/blobs" "$store_name/"
fi
done
log "Blob store backup completed"
else
log "WARNING: Blob stores directory not found"
fi
}
Configuration backup
backup_configuration() {
local backup_dir="$1"
log "Backing up Nexus configuration"
local config_items=(
"etc"
"log"
"tmp"
"orient.cfg"
)
for item in "${config_items[@]}"; do
if [ -e "$NEXUS_DATA_DIR/$item" ]; then
tar -czf "$backup_dir/$item-$(date +%Y%m%d-%H%M%S).tar.gz" \
-C "$NEXUS_DATA_DIR" "$item"
fi
done
log "Configuration backup completed"
}
list_blob_stores() {
log "Available blob stores:"
if [ -d "$NEXUS_DATA_DIR/blobs" ]; then
for store in "$NEXUS_DATA_DIR/blobs"/*; do
if [ -d "$store" ]; then
local store_name=$(basename "$store")
local size=$(du -sh "$store" | cut -f1)
log " - $store_name ($size)"
fi
done
else
log "No blob stores found"
fi
}
migrate_blob_store() {
local source_store="$1"
local target_path="$2"
local migration_type="${3:-copy}"
log "Starting blob store migration: $source_store -> $target_path"
if [ ! -d "$NEXUS_DATA_DIR/blobs/$source_store" ]; then
log "ERROR: Source blob store not found: $source_store"
return 1
fi
mkdir -p "$target_path"
case "$migration_type" in
"copy")
log "Copying blob store (source preserved)"
rsync -avP "$NEXUS_DATA_DIR/blobs/$source_store/" "$target_path/"
;;
"move")
log "Moving blob store (source will be removed)"
rsync -avP --remove-source-files "$NEXUS_DATA_DIR/blobs/$source_store/" "$target_path/"
find "$NEXUS_DATA_DIR/blobs/$source_store" -type d -empty -delete
;;
*)
log "ERROR: Invalid migration type: $migration_type (use 'copy' or 'move')"
return 1
;;
esac
# Verify migration
local source_count=$(find "$NEXUS_DATA_DIR/blobs/$source_store" -type f | wc -l)
local target_count=$(find "$target_path" -type f | wc -l)
if [ "$migration_type" = "copy" ] && [ "$source_count" -eq "$target_count" ]; then
log "Migration verified: $target_count files copied successfully"
elif [ "$migration_type" = "move" ] && [ "$target_count" -gt 0 ]; then
log "Migration verified: $target_count files moved successfully"
else
log "WARNING: Migration verification failed (source: $source_count, target: $target_count)"
fi
}
Usage information
usage() {
cat << EOF
Usage: $0 [options]
Commands:
list List all blob stores
migrate Migrate blob store (copy by default)
migrate move Move blob store to new location
Examples:
$0 list
$0 migrate default /mnt/new-storage/default
$0 migrate default /mnt/new-storage/default move
EOF
}
Main execution
case "${1:-}" in
"list")
list_blob_stores
;;
"migrate")
if [ $# -lt 3 ]; then
usage
exit 1
fi
# Stop Nexus during migration
log "Stopping Nexus for blob store migration"
sudo systemctl stop nexus
migrate_blob_store "$2" "$3" "${4:-copy}"
log "Starting Nexus after migration"
sudo systemctl start nexus
;;
*)
usage
exit 1
;;
esac
Create disaster recovery script
This script handles full system restoration from encrypted backups.
list_backups() {
log "Available backup files:"
# Local backups
if [ -d "$BACKUP_BASE_DIR/snapshots" ]; then
find "$BACKUP_BASE_DIR/snapshots" -name "*.tar.gz.gpg" -printf "%T@ %Tc %p\n" | sort -rn | head -10 | while read -r epoch date time tz file; do
log " Local: $(basename "$file") ($date $time)"
done
fi
# S3 backups (if configured)
if command -v aws >/dev/null && [ -n "${S3_BUCKET:-}" ]; then
log " S3 backups in bucket: $S3_BUCKET"
aws s3 ls "s3://$S3_BUCKET/" --recursive | tail -10 | while read -r date time size file; do
log " S3: $(basename "$file") ($date $time)"
done
fi
}
Download backup from S3
download_backup() {
local backup_name="$1"
local local_path="$BACKUP_BASE_DIR/snapshots/$backup_name"
if [ -f "$local_path" ]; then
log "Backup already exists locally: $local_path"
echo "$local_path"
return 0
fi
if command -v aws >/dev/null && [ -n "${S3_BUCKET:-}" ]; then
log "Downloading backup from S3: $backup_name"
aws s3 cp "s3://$S3_BUCKET/$backup_name" "$local_path"
echo "$local_path"
else
log "ERROR: Cannot download backup (AWS CLI not configured)"
return 1
fi
}
Decrypt and extract backup
extract_backup() {
local backup_file="$1"
local extract_dir="$RECOVERY_DIR/staging/$(basename "$backup_file" .tar.gz.gpg)"
log "Extracting backup: $(basename "$backup_file")"
# Clean staging area
rm -rf "$extract_dir"
mkdir -p "$extract_dir"
# Decrypt and extract
gpg --trust-model always --decrypt "$backup_file" | tar -xzf - -C "$extract_dir"
# Verify extraction
if [ -f "$extract_dir"/*/backup-metadata.json ]; then
log "Backup extracted successfully to: $extract_dir"
echo "$extract_dir"
else
log "ERROR: Backup extraction failed or incomplete"
return 1
fi
}
Restore from extracted backup
restore_nexus() {
local extract_dir="$1"
local force_restore="${2:-false}"
# Find the actual backup directory
local backup_content_dir
backup_content_dir=$(find "$extract_dir" -maxdepth 1 -type d -name "nexus-backup-*" | head -1)
if [ -z "$backup_content_dir" ]; then
log "ERROR: Backup content directory not found in $extract_dir"
return 1
fi
# Display backup metadata
if [ -f "$backup_content_dir/backup-metadata.json" ]; then
log "Backup metadata:"
cat "$backup_content_dir/backup-metadata.json" | jq .
fi
# Safety check
if [ "$force_restore" != "true" ] && [ -d "$NEXUS_DATA_DIR" ]; then
log "WARNING: Nexus data directory exists. This will overwrite existing data."
log "Use --force to proceed with restoration."
return 1
fi
# Stop Nexus
log "Stopping Nexus Repository Manager"
sudo systemctl stop nexus || true
# Backup existing data
if [ -d "$NEXUS_DATA_DIR" ]; then
local backup_existing="$RECOVERY_DIR/existing-$(date +%Y%m%d-%H%M%S)"
log "Backing up existing data to: $backup_existing"
sudo mv "$NEXUS_DATA_DIR" "$backup_existing"
fi
# Create new data directory
sudo mkdir -p "$NEXUS_DATA_DIR"
# Restore database
if [ -f "$backup_content_dir"/orientdb-*.tar.gz ]; then
log "Restoring OrientDB database"
sudo tar -xzf "$backup_content_dir"/orientdb-*.tar.gz -C "$NEXUS_DATA_DIR"
fi
# Restore blob stores
if [ -d "$backup_content_dir/blob-stores" ]; then
log "Restoring blob stores"
sudo mkdir -p "$NEXUS_DATA_DIR/blobs"
for blob_archive in "$backup_content_dir/blob-stores"/*.tar.gz; do
if [ -f "$blob_archive" ]; then
local store_name=$(basename "$blob_archive" | sed 's/-[0-9]-[0-9].tar.gz$//')
log "Restoring blob store: $store_name"
sudo tar -xzf "$blob_archive" -C "$NEXUS_DATA_DIR/blobs"
fi
done
fi
# Restore configuration files
for config_archive in "$backup_content_dir"/etc-.tar.gz "$backup_content_dir"/orient.cfg-.tar.gz; do
if [ -f "$config_archive" ]; then
log "Restoring configuration: $(basename "$config_archive")"
sudo tar -xzf "$config_archive" -C "$NEXUS_DATA_DIR"
fi
done
# Fix permissions
sudo chown -R nexus:nexus "$NEXUS_DATA_DIR"
sudo chmod -R 755 "$NEXUS_DATA_DIR"
# Start Nexus
log "Starting Nexus Repository Manager"
sudo systemctl start nexus
# Wait for startup and verify
local retries=0
while ! curl -sf http://localhost:8081/service/rest/v1/status > /dev/null; do
if [ $retries -ge 30 ]; then
log "ERROR: Nexus failed to start within 5 minutes"
return 1
fi
sleep 10
((retries++))
done
log "Nexus Repository Manager restored and started successfully"
}
Usage information
usage() {
cat << EOF
Usage: $0 [options]
Commands:
list List available backups
restore [--force] Restore from backup file
download Download backup from S3
Examples:
$0 list
$0 restore /path/to/backup.tar.gz.gpg
$0 restore /path/to/backup.tar.gz.gpg --force
$0 download nexus-backup-20241201-120000.tar.gz.gpg
EOF
}
Main execution
case "${1:-}" in
"list")
list_backups
;;
"restore")
if [ $# -lt 2 ]; then
usage
exit 1
fi
backup_file="$2"
force_restore="false"
if [ "${3:-}" = "--force" ]; then
force_restore="true"
fi
if [ ! -f "$backup_file" ]; then
log "ERROR: Backup file not found: $backup_file"
exit 1
fi
extract_dir=$(extract_backup "$backup_file")
restore_nexus "$extract_dir" "$force_restore"
;;
"download")
if [ $# -lt 2 ]; then
usage
exit 1
fi
downloaded_file=$(download_backup "$2")
log "Downloaded: $downloaded_file"
;;
*)
usage
exit 1
;;
esac
Make scripts executable
Set proper permissions for all backup and recovery scripts.
# WARNING: This will overwrite existing data
sudo -u nexus-backup /opt/nexus-backup/scripts/nexus-restore.sh restore /path/to/backup.tar.gz.gpg --force
5. Verify Recovery
Check service status: systemctl status nexus
Test web interface: http://localhost:8081
Verify repositories and artifacts
Partial Recovery Scenarios
Blob Store Corruption
Stop Nexus: sudo systemctl stop nexus
Extract specific blob store from backup
Replace corrupted blob store
Start Nexus: sudo systemctl start nexus
Configuration Corruption
Extract configuration files from backup
Replace corrupted configs in /opt/sonatype-work/nexus3/etc/
Restart Nexus
Contact Information
System Administrator: admin@example.com
Emergency Contact: +1-555-0123
Backup Location: S3 bucket nexus-backups-example
Recovery Time Objectives
RPO (Recovery Point Objective): 24 hours (daily backups)
RTO (Recovery Time Objective): 2 hours (complete restoration)
Last Updated: $(date)
Set up monitoring and alerting
Create a monitoring script to check backup health and send alerts.
check_recent_backup() {
local latest_backup
latest_backup=$(find "$BACKUP_BASE_DIR/snapshots" -name "*.tar.gz.gpg" -type f -printf '%T@ %p\n' | sort -n | tail -1 | cut -d' ' -f2-)
if [ -z "$latest_backup" ]; then
log "CRITICAL: No backups found"
return 1
fi
local backup_age
backup_age=$(stat -c %Y "$latest_backup")
local current_time=$(date +%s)
local age_hours=$(( (current_time - backup_age) / 3600 ))
if [ $age_hours -gt $MAX_BACKUP_AGE_HOURS ]; then
log "WARNING: Latest backup is $age_hours hours old (max: $MAX_BACKUP_AGE_HOURS)"
return 1
else
log "OK: Latest backup is $age_hours hours old"
return 0
fi
}
Check backup service status
check_backup_service() {
if systemctl is-enabled nexus-backup.timer >/dev/null 2>&1; then
if systemctl is-active nexus-backup.timer >/dev/null 2>&1; then
log "OK: Backup timer is active"
return 0
else
log "CRITICAL: Backup timer is not active"
return 1
fi
else
log "CRITICAL: Backup timer is not enabled"
return 1
fi
}
Send email alert
send_alert() {
local subject="$1"
local message="$2"
if command -v mail >/dev/null 2>&1; then
echo "$message" | mail -s "$subject" "$EMAIL_ALERT"
log "Alert sent to $EMAIL_ALERT"
else
log "WARNING: Cannot send email alert (mail command not available)"
fi
}
Main monitoring logic
main() {
local errors=0
local messages=""
if ! check_recent_backup; then
errors=$((errors + 1))
messages="${messages}Backup age check failed\n"
fi
if ! check_backup_service; then
errors=$((errors + 1))
messages="${messages}Backup service check failed\n"
fi
if [ $errors -gt 0 ]; then
local alert_message="Nexus backup monitoring detected $errors issues:\n\n${messages}\nHost: $(hostname)\nTime: $(date)"
send_alert "Nexus Backup Alert - $(hostname)" "$alert_message"
exit 1
else
log "All backup monitoring checks passed"
exit 0
fi
}
main "$@"
Want this handled for you? Setting up automated backups and disaster recovery once is straightforward. Keeping backup strategies tested, storage optimized, and recovery procedures updated across environments is the harder part. See how we run infrastructure like this for European teams needing reliable repository management.
Automated install script
Run this to automate the entire setup
install.sh
#!/usr/bin/env bash
set -euo pipefail
# Nexus Repository Manager 3 Automated Backup and Disaster Recovery Setup
# Production-ready installation script with blob store migration support
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m'
# Configuration
NEXUS_DATA_DIR="/opt/sonatype-work/nexus3"
BACKUP_ROOT="/opt/nexus-backup"
SCRIPT_USER="nexus-backup"
AWS_REGION="${AWS_REGION:-us-east-1}"
# Print colored output
print_status() { echo -e "${BLUE}[INFO]${NC} $1"; }
print_success() { echo -e "${GREEN}[SUCCESS]${NC} $1"; }
print_warning() { echo -e "${YELLOW}[WARNING]${NC} $1"; }
print_error() { echo -e "${RED}[ERROR]${NC} $1"; }
# Usage information
usage() {
cat << EOF
Usage: $0 [OPTIONS]
Options:
--nexus-data-dir PATH Nexus data directory (default: $NEXUS_DATA_DIR)
--backup-dir PATH Backup root directory (default: $BACKUP_ROOT)
--aws-region REGION AWS region for S3 backups (default: $AWS_REGION)
--help Show this help message
Example:
$0 --nexus-data-dir /opt/nexus3 --backup-dir /backup/nexus
EOF
exit 1
}
# Parse command line arguments
while [[ $# -gt 0 ]]; do
case $1 in
--nexus-data-dir)
NEXUS_DATA_DIR="$2"
shift 2
;;
--backup-dir)
BACKUP_ROOT="$2"
shift 2
;;
--aws-region)
AWS_REGION="$2"
shift 2
;;
--help)
usage
;;
*)
print_error "Unknown option: $1"
usage
;;
esac
done
# Cleanup on failure
cleanup() {
if [[ $? -ne 0 ]]; then
print_error "Installation failed. Cleaning up..."
if id "$SCRIPT_USER" >/dev/null 2>&1; then
userdel -r "$SCRIPT_USER" 2>/dev/null || true
fi
rm -rf "$BACKUP_ROOT" 2>/dev/null || true
fi
}
trap cleanup ERR
# Check if running as root
if [[ $EUID -ne 0 ]]; then
print_error "This script must be run as root or with sudo"
exit 1
fi
# Detect distribution and set package manager
detect_distro() {
if [[ ! -f /etc/os-release ]]; then
print_error "Cannot detect Linux distribution"
exit 1
fi
. /etc/os-release
case "$ID" in
ubuntu|debian)
PKG_MGR="apt"
PKG_UPDATE="apt update"
PKG_INSTALL="apt install -y"
PKG_UPGRADE="apt upgrade -y"
POSTGRES_CLIENT="postgresql-client-common"
GPG_PKG="gpg"
;;
almalinux|rocky|centos|rhel|ol|fedora)
PKG_MGR="dnf"
PKG_UPDATE="dnf check-update || true"
PKG_INSTALL="dnf install -y"
PKG_UPGRADE="dnf update -y"
POSTGRES_CLIENT="postgresql"
GPG_PKG="gnupg2"
;;
amzn)
PKG_MGR="yum"
PKG_UPDATE="yum check-update || true"
PKG_INSTALL="yum install -y"
PKG_UPGRADE="yum update -y"
POSTGRES_CLIENT="postgresql"
GPG_PKG="gnupg2"
;;
*)
print_error "Unsupported distribution: $ID"
exit 1
;;
esac
print_success "Detected distribution: $PRETTY_NAME"
}
# Install packages
install_packages() {
local step="$1"
print_status "[$step] Installing backup utilities and dependencies..."
$PKG_UPDATE
$PKG_UPGRADE
$PKG_INSTALL rsync gzip tar "$GPG_PKG" curl jq "$POSTGRES_CLIENT" awscli
print_success "All required packages installed"
}
# Create backup user and directories
setup_directories() {
local step="$1"
print_status "[$step] Creating backup directories and user..."
# Create backup user
if ! id "$SCRIPT_USER" >/dev/null 2>&1; then
useradd -r -s /bin/bash -d "$BACKUP_ROOT" -m "$SCRIPT_USER"
print_success "Created backup user: $SCRIPT_USER"
else
print_warning "User $SCRIPT_USER already exists"
fi
# Create directory structure
mkdir -p "$BACKUP_ROOT"/{scripts,snapshots,blob-stores,logs,recovery/{staging,restored}}
# Set proper permissions
chown -R "$SCRIPT_USER":"$SCRIPT_USER" "$BACKUP_ROOT"
chmod 750 "$BACKUP_ROOT"
chmod 755 "$BACKUP_ROOT"/scripts
chmod 750 "$BACKUP_ROOT"/{snapshots,blob-stores,logs,recovery}
print_success "Backup directories created with secure permissions"
}
# Configure GPG encryption
setup_gpg() {
local step="$1"
print_status "[$step] Configuring GPG encryption for backups..."
if ! sudo -u "$SCRIPT_USER" gpg --list-keys | grep -q nexus-backup; then
sudo -u "$SCRIPT_USER" gpg --batch --generate-key << EOF
Key-Type: RSA
Key-Length: 4096
Subkey-Type: RSA
Subkey-Length: 4096
Name-Real: Nexus Backup
Name-Email: nexus-backup@$(hostname -d 2>/dev/null || echo localhost)
Expire-Date: 2y
Passphrase:
%commit
EOF
print_success "GPG encryption keys generated"
else
print_warning "GPG keys already exist for nexus-backup"
fi
}
# Create backup scripts
create_backup_scripts() {
local step="$1"
print_status "[$step] Creating backup and recovery scripts..."
# Main backup script
cat > "$BACKUP_ROOT/scripts/nexus-backup.sh" << 'EOF'
#!/usr/bin/env bash
set -euo pipefail
NEXUS_DATA_DIR="/opt/sonatype-work/nexus3"
BACKUP_ROOT="/opt/nexus-backup"
LOG_FILE="$BACKUP_ROOT/logs/backup-$(date +%Y%m%d).log"
RETENTION_DAYS=30
exec 2>&1 | tee -a "$LOG_FILE"
log() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $*"
}
stop_nexus() {
log "Stopping Nexus Repository Manager"
sudo systemctl stop nexus
sleep 10
}
start_nexus() {
log "Starting Nexus Repository Manager"
sudo systemctl start nexus
local retries=0
while ! curl -sf http://localhost:8081/service/rest/v1/status > /dev/null; do
if [ $retries -ge 30 ]; then
log "ERROR: Nexus failed to start within 5 minutes"
exit 1
fi
sleep 10
((retries++))
done
log "Nexus Repository Manager started successfully"
}
backup_database() {
local backup_dir="$1"
log "Backing up OrientDB database"
if [ -d "$NEXUS_DATA_DIR/db" ]; then
tar -czf "$backup_dir/orientdb-$(date +%Y%m%d-%H%M%S).tar.gz" -C "$NEXUS_DATA_DIR" db/
log "Database backup completed"
else
log "WARNING: Database directory not found"
fi
}
backup_blob_stores() {
local backup_dir="$1"
log "Backing up blob stores"
local blob_backup_dir="$backup_dir/blob-stores"
mkdir -p "$blob_backup_dir"
if [ -d "$NEXUS_DATA_DIR/blobs" ]; then
find "$NEXUS_DATA_DIR/blobs" -type f -name "*.properties" > "$blob_backup_dir/blob-manifest.txt"
for blob_store in "$NEXUS_DATA_DIR/blobs"/*; do
if [ -d "$blob_store" ]; then
local store_name=$(basename "$blob_store")
log "Backing up blob store: $store_name"
tar -czf "$blob_backup_dir/$store_name-$(date +%Y%m%d-%H%M%S).tar.gz" -C "$NEXUS_DATA_DIR/blobs" "$store_name/"
fi
done
log "Blob store backup completed"
fi
}
backup_configuration() {
local backup_dir="$1"
log "Backing up Nexus configuration"
local config_items=("etc" "log" "tmp")
for item in "${config_items[@]}"; do
if [ -e "$NEXUS_DATA_DIR/$item" ]; then
tar -czf "$backup_dir/${item}-$(date +%Y%m%d-%H%M%S).tar.gz" -C "$NEXUS_DATA_DIR" "$item/"
fi
done
log "Configuration backup completed"
}
cleanup_old_backups() {
log "Cleaning up backups older than $RETENTION_DAYS days"
find "$BACKUP_ROOT/snapshots" -type f -mtime +$RETENTION_DAYS -delete
}
main() {
local snapshot_dir="$BACKUP_ROOT/snapshots/$(date +%Y%m%d-%H%M%S)"
mkdir -p "$snapshot_dir"
log "Starting backup process"
stop_nexus
trap start_nexus EXIT
backup_database "$snapshot_dir"
backup_blob_stores "$snapshot_dir"
backup_configuration "$snapshot_dir"
start_nexus
trap - EXIT
cleanup_old_backups
log "Backup process completed successfully"
}
main "$@"
EOF
chmod 755 "$BACKUP_ROOT/scripts/nexus-backup.sh"
chown "$SCRIPT_USER":"$SCRIPT_USER" "$BACKUP_ROOT/scripts/nexus-backup.sh"
print_success "Backup scripts created"
}
# Create systemd timer
setup_systemd_timer() {
local step="$1"
print_status "[$step] Setting up systemd timer for automated backups..."
# Service file
cat > /etc/systemd/system/nexus-backup.service << EOF
[Unit]
Description=Nexus Repository Manager Backup
After=nexus.service
[Service]
Type=oneshot
User=$SCRIPT_USER
Group=$SCRIPT_USER
ExecStart=$BACKUP_ROOT/scripts/nexus-backup.sh
StandardOutput=journal
StandardError=journal
EOF
# Timer file
cat > /etc/systemd/system/nexus-backup.timer << EOF
[Unit]
Description=Run Nexus backup daily at 2 AM
Requires=nexus-backup.service
[Timer]
OnCalendar=daily
Persistent=true
RandomizedDelaySec=30m
[Install]
WantedBy=timers.target
EOF
systemctl daemon-reload
systemctl enable nexus-backup.timer
systemctl start nexus-backup.timer
print_success "Systemd timer configured and enabled"
}
# Verify installation
verify_installation() {
local step="$1"
print_status "[$step] Verifying installation..."
# Check user exists
if ! id "$SCRIPT_USER" >/dev/null 2>&1; then
print_error "Backup user not created"
exit 1
fi
# Check directories
if [[ ! -d "$BACKUP_ROOT" ]]; then
print_error "Backup directory not created"
exit 1
fi
# Check scripts are executable
if [[ ! -x "$BACKUP_ROOT/scripts/nexus-backup.sh" ]]; then
print_error "Backup script not executable"
exit 1
fi
# Check systemd timer
if ! systemctl is-enabled nexus-backup.timer >/dev/null 2>&1; then
print_error "Systemd timer not enabled"
exit 1
fi
# Check timer status
if systemctl is-active nexus-backup.timer >/dev/null 2>&1; then
print_success "Systemd timer is active"
else
print_warning "Systemd timer is not active"
fi
print_success "Installation verification completed"
}
# Main installation flow
main() {
print_status "Starting Nexus Repository Manager backup and disaster recovery setup"
detect_distro
install_packages "1/6"
setup_directories "2/6"
setup_gpg "3/6"
create_backup_scripts "4/6"
setup_systemd_timer "5/6"
verify_installation "6/6"
print_success "Nexus backup and disaster recovery setup completed successfully!"
echo
print_status "Configuration Summary:"
echo " - Backup directory: $BACKUP_ROOT"
echo " - Backup user: $SCRIPT_USER"
echo " - Nexus data directory: $NEXUS_DATA_DIR"
echo " - Automated backups: Daily at 2 AM (systemd timer)"
echo
print_status "Next steps:"
echo " 1. Test backup: sudo -u $SCRIPT_USER $BACKUP_ROOT/scripts/nexus-backup.sh"
echo " 2. Configure AWS credentials for S3 backup (optional)"
echo " 3. Review backup retention settings in backup script"
}
main "$@"
Review the script before running. Execute with: bash install.sh