Backup & Restore
Protect your Nexo Share data with proper backup strategies.
What to Backup
Nexo Share has three critical components:
- PostgreSQL Database - Users, shares, settings, metadata
- Upload Files - The actual files users have shared
- Docker Compose Configuration - Your environment setup
Manual Backup
Database Backup
Create SQL dump:
docker compose exec postgres pg_dump -U nexoshare nexoshare > backup_$(date +%Y%m%d).sql
Compressed backup (recommended):
docker compose exec postgres pg_dump -U nexoshare nexoshare | gzip > backup_$(date +%Y%m%d).sql.gz
Files Backup
Simple copy (for small installations):
cp -r ./uploads ./uploads_backup_$(date +%Y%m%d)
Efficient rsync (for large installations):
rsync -a ./uploads/ /backup/Nexoshare/uploads_$(date +%Y%m%d)/
Compressed archive:
tar -czf uploads_backup_$(date +%Y%m%d).tar.gz ./uploads
Configuration Backup
cp docker-compose.yml docker-compose.yml.backup
Save .env file if using environment variables:
cp .env .env.backup
Automated Backup Script
Create /usr/local/bin/backup-Nexoshare.sh:
#!/bin/bash
# Configuration
BACKUP_DIR="/backup/Nexoshare"
Nexoshare_DIR="/home/user/Nexoshare"
RETENTION_DAYS=30
# Create backup directory
mkdir -p "$BACKUP_DIR"
# Timestamp for backup
DATE=$(date +%Y%m%d_%H%M%S)
# Log file
LOG="$BACKUP_DIR/backup_$DATE.log"
echo "Nexo Share Backup Started: $(date)" > "$LOG"
# Navigate to Nexo Share directory
cd "$Nexoshare_DIR" || exit 1
# Backup database
echo "Backing up database..." | tee -a "$LOG"
docker compose exec -T postgres pg_dump -U nexoshare nexoshare | gzip > "$BACKUP_DIR/db_$DATE.sql.gz"
if [ $? -eq 0 ]; then
echo "Database backup successful: db_$DATE.sql.gz" | tee -a "$LOG"
else
echo "ERROR: Database backup failed!" | tee -a "$LOG"
exit 1
fi
# Backup files
echo "Backing up files..." | tee -a "$LOG"
rsync -a --info=progress2 ./uploads/ "$BACKUP_DIR/uploads_$DATE/"
if [ $? -eq 0 ]; then
echo "Files backup successful: uploads_$DATE/" | tee -a "$LOG"
else
echo "ERROR: Files backup failed!" | tee -a "$LOG"
exit 1
fi
# Backup configuration
echo "Backing up configuration..." | tee -a "$LOG"
cp docker-compose.yml "$BACKUP_DIR/docker-compose_$DATE.yml"
# Calculate backup size
DB_SIZE=$(du -sh "$BACKUP_DIR/db_$DATE.sql.gz" | cut -f1)
FILES_SIZE=$(du -sh "$BACKUP_DIR/uploads_$DATE" | cut -f1)
echo "Backup sizes: Database=$DB_SIZE, Files=$FILES_SIZE" | tee -a "$LOG"
# Cleanup old backups
echo "Cleaning up old backups (older than $RETENTION_DAYS days)..." | tee -a "$LOG"
find "$BACKUP_DIR" -name "db_*.sql.gz" -mtime +$RETENTION_DAYS -delete
find "$BACKUP_DIR" -name "uploads_*" -type d -mtime +$RETENTION_DAYS -exec rm -rf {} +
find "$BACKUP_DIR" -name "docker-compose_*.yml" -mtime +$RETENTION_DAYS -delete
find "$BACKUP_DIR" -name "backup_*.log" -mtime +$RETENTION_DAYS -delete
echo "Nexo Share Backup Completed: $(date)" | tee -a "$LOG"
Make executable:
sudo chmod +x /usr/local/bin/backup-Nexoshare.sh
Test the script:
sudo /usr/local/bin/backup-Nexoshare.sh
Schedule with Cron
Daily backup at 2 AM:
sudo crontab -e
Add:
0 2 * * * /usr/local/bin/backup-Nexoshare.sh
Weekly backup on Sunday at 3 AM:
0 3 * * 0 /usr/local/bin/backup-Nexoshare.sh
View cron logs:
grep CRON /var/log/syslog
Remote Backup
Backup to Remote Server (rsync)
#!/bin/bash
BACKUP_DIR="/backup/Nexoshare"
REMOTE_USER="backup"
REMOTE_HOST="backup.company.com"
REMOTE_DIR="/backups/Nexoshare"
# After local backup completes
rsync -avz --delete "$BACKUP_DIR/" "$REMOTE_USER@$REMOTE_HOST:$REMOTE_DIR/"
Setup SSH keys for passwordless transfer:
ssh-keygen -t ed25519 -C "Nexoshare-backup"
ssh-copy-id [email protected]
Backup to Cloud Storage (rclone)
Install rclone:
curl https://rclone.org/install.sh | sudo bash
Configure (example: AWS S3):
rclone config
# Follow prompts to add S3 remote named "s3backup"
Add to backup script:
# Upload to S3
rclone sync "$BACKUP_DIR" s3backup:Nexoshare-backups \
--transfers 4 \
--checkers 8 \
--progress
Restore Procedures
Full Restore
Prerequisites: Fresh Nexo Share installation with same version.
Step 1: Stop Services
cd /path/to/Nexoshare
docker compose down
Step 2: Restore Files
# Remove current files
rm -rf ./uploads/*
# Restore from backup
rsync -a /backup/Nexoshare/uploads_YYYYMMDD_HHMMSS/ ./uploads/
# Or from tar.gz
tar -xzf uploads_backup_YYYYMMDD.tar.gz
Step 3: Restore Database
# Start only PostgreSQL
docker compose up -d postgres
# Wait for database to be ready
sleep 10
# Restore from backup
zcat /backup/Nexoshare/db_YYYYMMDD_HHMMSS.sql.gz | \
docker compose exec -T postgres psql -U nexoshare nexoshare
# Or from uncompressed backup
docker compose exec -T postgres psql -U nexoshare nexoshare < backup_YYYYMMDD.sql
Step 4: Start All Services
docker compose up -d
Step 5: Verify
docker compose logs -f
Check for:
✅ DB Ready & Up-to-date- No error messages
- Login works
- Files are accessible
Partial Restore
Restore Only Database
Useful for recovering from database corruption while keeping files.
# Stop Nexo Share (keep postgres running)
docker compose stop nexoshare
# Backup current database (just in case)
docker compose exec postgres pg_dump -U nexoshare nexoshare > current_db_backup.sql
# Drop and recreate database
docker compose exec postgres psql -U nexoshare -c "DROP DATABASE IF EXISTS nexoshare;"
docker compose exec postgres psql -U nexoshare -c "CREATE DATABASE nexoshare;"
# Restore from backup
zcat db_backup.sql.gz | docker compose exec -T postgres psql -U nexoshare nexoshare
# Restart Nexo Share
docker compose start nexoshare
Restore Only Files
Useful for recovering deleted shares while keeping user accounts.
# Identify share ID from database
docker compose exec postgres psql -U nexoshare nexoshare -c \
"SELECT id, name FROM shares WHERE name LIKE '%important%';"
# Restore specific share
SHARE_ID="abc123def456"
rsync -a /backup/Nexoshare/uploads_YYYYMMDD/$SHARE_ID/ ./uploads/$SHARE_ID/
Restore Single User
# Export user from backup database
zcat db_backup.sql.gz | grep "INSERT INTO users" | grep "[email protected]" > user_restore.sql
# Import to current database
docker compose exec -T postgres psql -U nexoshare nexoshare < user_restore.sql
Disaster Recovery
Scenario 1: Complete Server Loss
Requirements:
- Recent backups on external storage
- New server with Docker installed
Recovery Steps:
- Install Docker and Docker Compose on new server
- Clone/download Nexo Share:
mkdir Nexo Share && cd Nexo Share
# Copy your docker-compose.yml backup
- Restore files:
# Download from remote backup
rsync -avz [email protected]:/backups/Nexoshare/uploads_LATEST/ ./uploads/
- Start PostgreSQL only:
docker compose up -d postgres
sleep 10
- Restore database:
# Download and restore
scp [email protected]:/backups/Nexoshare/db_LATEST.sql.gz .
zcat db_LATEST.sql.gz | docker compose exec -T postgres psql -U nexoshare nexoshare
- Start all services:
docker compose up -d
- Update DNS to point to new server IP
RTO (Recovery Time Objective): 30-60 minutes depending on data size.
Scenario 2: Database Corruption
Symptoms: Errors, missing data, application crashes.
Recovery:
docker compose down
docker compose up -d postgres
sleep 10
# Restore from most recent backup
zcat /backup/Nexoshare/db_LATEST.sql.gz | \
docker compose exec -T postgres psql -U nexoshare nexoshare
docker compose up -d
Data Loss: Changes since last backup.
Scenario 3: Ransomware/File Deletion
Symptoms: Files missing, encrypted, or corrupted.
Recovery:
# Stop Nexo Share immediately
docker compose down
# Restore files from clean backup
rm -rf ./uploads/*
rsync -a /backup/Nexoshare/uploads_BEFORE_INCIDENT/ ./uploads/
docker compose up -d
Prevention:
- Immutable backups (write-once storage)
- Air-gapped backup rotation
- Regular restore testing
Backup Verification
Test Database Restore
# Create test container
docker run -d --name test-postgres \
-e POSTGRES_PASSWORD=test \
-e POSTGRES_USER=nexoshare \
-e POSTGRES_DB=nexoshare \
postgres:17-alpine
# Restore backup to test container
zcat db_backup.sql.gz | docker exec -i test-postgres psql -U nexoshare nexoshare
# Verify data
docker exec test-postgres psql -U nexoshare nexoshare -c "SELECT COUNT(*) FROM users;"
docker exec test-postgres psql -U nexoshare nexoshare -c "SELECT COUNT(*) FROM shares;"
# Cleanup
docker stop test-postgres
docker rm test-postgres
Test Files Restore
# Create test directory
mkdir /tmp/restore-test
# Restore to test location
rsync -a ./uploads/ /tmp/restore-test/
# Verify file count and size
find ./uploads -type f | wc -l
find /tmp/restore-test -type f | wc -l
du -sh ./uploads
du -sh /tmp/restore-test
# Cleanup
rm -rf /tmp/restore-test
Backup Best Practices
3-2-1 Rule
- 3 copies of data (original + 2 backups)
- 2 different media (local disk + cloud/remote server)
- 1 offsite backup (different location)
Encryption
Encrypt sensitive backups:
# Encrypt database backup
gpg --symmetric --cipher-algo AES256 db_backup.sql.gz
# Decrypt when needed
gpg --decrypt db_backup.sql.gz.gpg | zcat | docker compose exec -T postgres psql ...
Retention Policy
Example retention schedule:
- Daily: Last 7 days
- Weekly: Last 4 weeks
- Monthly: Last 12 months
- Yearly: Last 3 years
Monitoring
Add backup monitoring:
#!/bin/bash
# Check if backup ran today
BACKUP_DIR="/backup/Nexoshare"
TODAY=$(date +%Y%m%d)
if ls $BACKUP_DIR/db_${TODAY}*.sql.gz 1> /dev/null 2>&1; then
echo "Backup OK: Found backup from $TODAY"
exit 0
else
echo "Backup FAILED: No backup from $TODAY found!"
# Send alert email
echo "Nexo Share backup failed on $(hostname)" | mail -s "BACKUP ALERT" [email protected]
exit 1
fi
Add to crontab (runs at 6 AM):
0 6 * * * /usr/local/bin/check-backup.sh
Storage Requirements
Estimate backup space needed:
Database: Usually small (< 100 MB for typical installations) Files: Depends on usage
- 100 users, 10 GB quota each = 1 TB
- With 30-day retention = 30 TB (if all data changes daily)
Realistic: Most shares are temporary, actual backup size is much smaller.
Monitoring Backup Size:
du -sh /backup/Nexoshare
Recovery Testing
Test quarterly:
- Restore to test server
- Verify login works
- Test file download
- Check database integrity
- Document any issues
Untested backups = No backups
Keep documentation updated with:
- Backup locations
- Restore procedures
- Access credentials
- Contact information
- Last successful test date