Skip to main content
WebsiteGitHub last commitGitHub commit activityGitHub IssuesDocker PullsDiscordLocalized

Nextcloud Backup & Recovery Guide

Backing up your Nextcloud instance is crucial for data protection and disaster recovery. This guide covers comprehensive backup strategies for both Docker-based and host installations, with a focus on MariaDB database backups.

Critical

Never skip backups! Data loss can happen due to hardware failure, human error, corrupted updates, or security incidents. Regular backups are your insurance policy.

Why Backup Your Nextcloud?

  • Data Protection: Protect against hardware failures, corrupted files, and accidental deletions
  • Security: Recover from ransomware attacks or security breaches
  • Updates: Safely rollback if an update causes issues
  • Migration: Move your Nextcloud instance to new hardware
  • Peace of Mind: Sleep better knowing your data is safe

What Needs to Be Backed Up

A complete Nextcloud backup includes:

  1. Database (MariaDB/MySQL/PostgreSQL)
  2. Nextcloud Files (user data, config, apps)
  3. Configuration Files (including Docker Compose files)
  4. External Storage (if applicable)

Docker-Based Backup Strategies

Prerequisites

Before starting, ensure you have sufficient storage space and appropriate permissions:

# Check available disk space
df -h

# Create backup directory
sudo mkdir -p /backup/nextcloud
sudo chown -R $USER:$USER /backup/nextcloud

Method 1: Complete Docker Backup Script

Create a comprehensive backup script for Docker installations:

nextcloud-backup.sh
#!/bin/bash

# Nextcloud Docker Backup Script

# ── Static paths ───────────────────────────────────────────────────────────────
BACKUP_DIR="/backup/nextcloud"
NEXTCLOUD_DIR="/opt/docker/nextcloud" # folder containing docker-compose.yaml and .env
RETENTION_DAYS=30

# ── Colors ─────────────────────────────────────────────────────────────────────
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
CYAN='\033[0;36m'
NC='\033[0m'

# ── Load .env (line-by-line to handle special characters safely) ───────────────
ENV_FILE="${NEXTCLOUD_DIR}/.env"
if [ -f "${ENV_FILE}" ]; then
echo -e "${CYAN}Loading configuration from ${ENV_FILE}${NC}"
while IFS= read -r line || [ -n "$line" ]; do
line="${line%$'\r'}"
[[ -z "$line" || "$line" =~ ^[[:space:]]*# ]] && continue
if [[ "$line" =~ ^([A-Za-z_][A-Za-z0-9_]*)=(.*)$ ]]; then
key="${BASH_REMATCH[1]}"; val="${BASH_REMATCH[2]}"
[[ "$val" =~ ^\"(.*)\"$ ]] && val="${BASH_REMATCH[1]}"
[[ "$val" =~ ^\'(.*)\'$ ]] && val="${BASH_REMATCH[1]}"
printf -v "$key" '%s' "$val"
export "$key"
fi
done < "${ENV_FILE}"
else
echo -e "${YELLOW}No .env found at ${ENV_FILE} — using built-in defaults${NC}"
fi

# ── Resolve config (env file values take priority, then hardcoded fallbacks) ────
NC_NAME_HINT="${CONTAINER_NAME:-nextcloud}"
DB_NAME_HINT="${DB_CONTAINER_NAME:-mariadb}"
DB_NAME="${MYSQL_DATABASE:-${DB_NAME:-nextcloud}}"
DB_USER="${MYSQL_USER:-${DB_USER:-nextcloud}}"
DB_PASSWORD="${MYSQL_PASSWORD:-${DB_PASSWORD:-}}"

# ── Fuzzy container lookup — handles Docker Compose project-name prefixes ──────
# --filter name= does substring matching, e.g. finds "nextcloud-nextcloud-1"
CONTAINER_NAME=$(docker ps --filter "name=${NC_NAME_HINT}" --format '{{.Names}}' \
| grep -E -v '(cron|installer|nginx|backup|harp|redis)' | head -1)
DB_CONTAINER_NAME=$(docker ps --filter "name=${DB_NAME_HINT}" --format '{{.Names}}' | head -1)

echo -e "${CYAN}Using config:${NC}"
echo " Nextcloud dir : ${NEXTCLOUD_DIR}"
echo " Nextcloud container: ${CONTAINER_NAME:-NOT FOUND (hint: ${NC_NAME_HINT})}"
echo " DB container : ${DB_CONTAINER_NAME:-NOT FOUND (hint: ${DB_NAME_HINT})}"
echo " DB name : ${DB_NAME}"
echo " DB user : ${DB_USER}"
echo " Backup dir : ${BACKUP_DIR}"
echo ""

# ── Validate required config ───────────────────────────────────────────────────
if [ -z "${DB_PASSWORD}" ]; then
echo -e "${RED}ERROR: Database password is not set.${NC}"
echo " → Expected: MYSQL_PASSWORD in ${ENV_FILE}"
echo " → Or export DB_PASSWORD before running this script."
exit 1
fi

DATE=$(date +%Y%m%d_%H%M%S)
BACKUP_NAME="nextcloud_backup_${DATE}"

echo -e "${GREEN}Starting Nextcloud backup: ${BACKUP_NAME}${NC}"

# ── Create backup staging directory ────────────────────────────────────────────
if ! mkdir -p "${BACKUP_DIR}/${BACKUP_NAME}"; then
echo -e "${RED}ERROR: Could not create backup directory ${BACKUP_DIR}/${BACKUP_NAME}${NC}"
echo " → Check that ${BACKUP_DIR} exists and is writable by $(whoami)."
echo " → Run: sudo mkdir -p ${BACKUP_DIR} && sudo chown $(whoami) ${BACKUP_DIR}"
exit 1
fi

# ── Step 1: Verify containers are running ─────────────────────────────────────
echo -e "${YELLOW}Checking containers...${NC}"
if [ -z "${CONTAINER_NAME}" ]; then
echo -e "${RED}ERROR: Could not find a running Nextcloud container matching '${NC_NAME_HINT}'.${NC}"
echo " → Running containers: $(docker ps --format '{{.Names}}' | tr '\n' ' ')"
echo " → Start it with: cd ${NEXTCLOUD_DIR} && docker compose up -d"
rm -rf "${BACKUP_DIR:?}/${BACKUP_NAME:?}"
exit 1
fi
if [ -z "${DB_CONTAINER_NAME}" ]; then
echo -e "${RED}ERROR: Could not find a running database container matching '${DB_NAME_HINT}'.${NC}"
echo " → Running containers: $(docker ps --format '{{.Names}}' | tr '\n' ' ')"
echo " → Start it with: cd ${NEXTCLOUD_DIR} && docker compose up -d"
rm -rf "${BACKUP_DIR:?}/${BACKUP_NAME:?}"
exit 1
fi

# ── Step 2: Enable maintenance mode ────────────────────────────────────────────
echo -e "${YELLOW}Enabling maintenance mode...${NC}"
if ! docker exec -u 33 "${CONTAINER_NAME}" php occ maintenance:mode --on; then
echo -e "${RED}ERROR: Could not enable maintenance mode.${NC}"
echo " → Container '${CONTAINER_NAME}' is running but occ failed."
echo " → Check PHP/container health: docker logs ${CONTAINER_NAME} --tail 30"
exit 1
fi

# ── Step 3: Backup database ────────────────────────────────────────────────────
echo -e "${YELLOW}Backing up MariaDB database '${DB_NAME}'...${NC}"
DB_DUMP="${BACKUP_DIR}/${BACKUP_NAME}/database.sql"
# Try mysqldump first (older MariaDB), fall back to mariadb-dump (newer)
if ! docker exec "${DB_CONTAINER_NAME}" mysqldump -u "${DB_USER}" -p"${DB_PASSWORD}" "${DB_NAME}" > "${DB_DUMP}" 2>/dev/null; then
if ! docker exec "${DB_CONTAINER_NAME}" mariadb-dump -u "${DB_USER}" -p"${DB_PASSWORD}" "${DB_NAME}" > "${DB_DUMP}" 2>/dev/null; then
echo -e "${RED}ERROR: Database dump failed.${NC}"
echo " → Container : ${DB_CONTAINER_NAME}"
echo " → DB user : ${DB_USER}"
echo " → DB name : ${DB_NAME}"
echo " → Common causes:"
echo " • Wrong password — check MYSQL_PASSWORD in ${ENV_FILE}"
echo " • DB user lacks DUMP privileges — run SHOW GRANTS FOR '${DB_USER}'@'%';"
echo " • Container not ready — check: docker logs ${DB_CONTAINER_NAME} --tail 30"
docker exec -u 33 "${CONTAINER_NAME}" php occ maintenance:mode --off
rm -rf "${BACKUP_DIR}/${BACKUP_NAME}"
exit 1
fi
fi
# Verify dump is non-empty
if [ ! -s "${DB_DUMP}" ]; then
echo -e "${RED}ERROR: Database dump file is empty — dump command may have silently failed.${NC}"
echo " → Check: docker logs ${DB_CONTAINER_NAME} --tail 30"
docker exec -u 33 "${CONTAINER_NAME}" php occ maintenance:mode --off
rm -rf "${BACKUP_DIR}/${BACKUP_NAME}"
exit 1
fi
echo -e "${GREEN}Database backup completed ($(du -h "${DB_DUMP}" | cut -f1))${NC}"

# ── Step 4: Backup Nextcloud data directory ────────────────────────────────────
echo -e "${YELLOW}Backing up Nextcloud data directory (${NEXTCLOUD_DIR})...${NC}"
DATA_ARCHIVE="${BACKUP_DIR}/${BACKUP_NAME}/nextcloud_data.tar.gz"
if ! tar -czf "${DATA_ARCHIVE}" -C "${NEXTCLOUD_DIR}" .; then
echo -e "${RED}ERROR: Data directory backup failed.${NC}"
echo " → Source path : ${NEXTCLOUD_DIR}"
echo " → Common causes:"
echo " • Path does not exist — verify NEXTCLOUD_DIR is correct"
echo " • Permission denied — run: ls -la ${NEXTCLOUD_DIR}"
echo " • Not enough disk space — run: df -h ${BACKUP_DIR}"
docker exec -u 33 "${CONTAINER_NAME}" php occ maintenance:mode --off
rm -rf "${BACKUP_DIR}/${BACKUP_NAME}"
exit 1
fi
echo -e "${GREEN}Data backup completed ($(du -h "${DATA_ARCHIVE}" | cut -f1))${NC}"

# ── Step 5: Backup Docker Compose config ──────────────────────────────────────
echo -e "${YELLOW}Backing up Docker Compose configuration...${NC}"
for f in docker-compose.yaml docker-compose.yml .env; do
[ -f "${NEXTCLOUD_DIR}/${f}" ] && cp "${NEXTCLOUD_DIR}/${f}" "${BACKUP_DIR}/${BACKUP_NAME}/"
done

# ── Step 6: Write backup manifest ─────────────────────────────────────────────
cat > "${BACKUP_DIR}/${BACKUP_NAME}/backup_info.txt" << EOF
Nextcloud Backup Information
============================
Backup Date : $(date)
Backup Name : ${BACKUP_NAME}
Nextcloud container: ${CONTAINER_NAME}
DB container : ${DB_CONTAINER_NAME}
DB name : ${DB_NAME}
Nextcloud dir : ${NEXTCLOUD_DIR}

Files:
database.sql — MariaDB dump
nextcloud_data.tar.gz — Nextcloud data directory
docker-compose.yaml — Compose file (if found)
.env — Environment variables (if found)
EOF

# ── Step 7: Disable maintenance mode ──────────────────────────────────────────
echo -e "${YELLOW}Disabling maintenance mode...${NC}"
if ! docker exec -u 33 "${CONTAINER_NAME}" php occ maintenance:mode --off; then
echo -e "${RED}WARNING: Could not disable maintenance mode — Nextcloud may still be offline.${NC}"
echo " → Run manually: docker exec -u 33 ${CONTAINER_NAME} php occ maintenance:mode --off"
exit 1
fi

# ── Step 8: Create final archive ───────────────────────────────────────────────
echo -e "${YELLOW}Creating compressed archive...${NC}"
FINAL_ARCHIVE="${BACKUP_DIR}/${BACKUP_NAME}.tar.gz"
if ! tar -czf "${FINAL_ARCHIVE}" -C "${BACKUP_DIR}" "${BACKUP_NAME}/"; then
echo -e "${RED}ERROR: Could not create final archive ${FINAL_ARCHIVE}${NC}"
echo " → Staging files are still at ${BACKUP_DIR}/${BACKUP_NAME}/"
echo " → Check disk space: df -h ${BACKUP_DIR}"
exit 1
fi
rm -rf "${BACKUP_DIR}/${BACKUP_NAME}"

# ── Step 9: Prune old backups ──────────────────────────────────────────────────
echo -e "${YELLOW}Removing backups older than ${RETENTION_DAYS} days...${NC}"
find "${BACKUP_DIR}" -name "nextcloud_backup_*.tar.gz" -mtime +${RETENTION_DAYS} -delete

BACKUP_SIZE=$(du -h "${FINAL_ARCHIVE}" | cut -f1)
echo -e "${GREEN}Backup complete!${NC}"
echo " Location : ${FINAL_ARCHIVE}"
echo " Size : ${BACKUP_SIZE}"

# Optional: uncomment to send an email notification
# echo "Nextcloud backup completed: ${BACKUP_NAME} (${BACKUP_SIZE})" | mail -s "Nextcloud Backup Success" admin@yourdomain.com

Method 2: Individual Component Backup

For more granular control, you can backup components individually:

Database Backup

# Create database backup
docker exec mariadb mysqldump -u nextcloud -pYOUR_PASSWORD nextcloud > nextcloud_db_$(date +%Y%m%d).sql

# Compress the backup
gzip nextcloud_db_$(date +%Y%m%d).sql

# Alternative: Direct compressed backup
docker exec mariadb mysqldump -u nextcloud -pYOUR_PASSWORD nextcloud | gzip > nextcloud_db_$(date +%Y%m%d).sql.gz

Data Directory Backup

# Stop containers for consistent backup
docker compose down

# Backup data directory
tar -czf nextcloud_data_$(date +%Y%m%d).tar.gz -C /var/docker/nextcloud .

# Start containers
docker compose up -d

Configuration Backup

# Backup Docker configuration
cp /var/docker/nextcloud/docker-compose.yaml /backup/
cp /var/docker/nextcloud/.env /backup/

# Backup Nextcloud config
cp /var/docker/nextcloud/nextcloud/config/config.php /backup/

Host Installation Backup Strategies

Method 1: Complete Host Backup Script

For traditional server installations:

nextcloud-host-backup.sh
#!/bin/bash

# Nextcloud Host Installation Backup Script

# Configuration
BACKUP_DIR="/backup/nextcloud"
NEXTCLOUD_DIR="/var/www/nextcloud"
NEXTCLOUD_DATA_DIR="/var/nextcloud/data"
DB_NAME="nextcloud"
DB_USER="nextcloud"
DB_PASSWORD="YOUR_DB_PASSWORD"
WEB_USER="www-data"
DATE=$(date +%Y%m%d_%H%M%S)
BACKUP_NAME="nextcloud_host_backup_${DATE}"

echo "Starting Nextcloud host backup: ${BACKUP_NAME}"

# Create backup directory
mkdir -p "${BACKUP_DIR}/${BACKUP_NAME}"

# Enable maintenance mode
sudo -u ${WEB_USER} php ${NEXTCLOUD_DIR}/occ maintenance:mode --on

# Backup database
echo "Backing up database..."
mysqldump -u ${DB_USER} -p${DB_PASSWORD} ${DB_NAME} > "${BACKUP_DIR}/${BACKUP_NAME}/database.sql"

# Backup Nextcloud installation
echo "Backing up Nextcloud installation..."
tar -czf "${BACKUP_DIR}/${BACKUP_NAME}/nextcloud_install.tar.gz" -C $(dirname ${NEXTCLOUD_DIR}) $(basename ${NEXTCLOUD_DIR})

# Backup data directory (if separate)
if [ "${NEXTCLOUD_DATA_DIR}" != "${NEXTCLOUD_DIR}/data" ]; then
echo "Backing up data directory..."
tar -czf "${BACKUP_DIR}/${BACKUP_NAME}/nextcloud_data.tar.gz" -C $(dirname ${NEXTCLOUD_DATA_DIR}) $(basename ${NEXTCLOUD_DATA_DIR})
fi

# Backup web server configuration
echo "Backing up web server configuration..."
if [ -d "/etc/nginx" ]; then
tar -czf "${BACKUP_DIR}/${BACKUP_NAME}/nginx_config.tar.gz" -C /etc nginx
fi
if [ -d "/etc/apache2" ]; then
tar -czf "${BACKUP_DIR}/${BACKUP_NAME}/apache_config.tar.gz" -C /etc apache2
fi

# Disable maintenance mode
sudo -u ${WEB_USER} php ${NEXTCLOUD_DIR}/occ maintenance:mode --off

# Create backup archive
cd "${BACKUP_DIR}"
tar -czf "${BACKUP_NAME}.tar.gz" "${BACKUP_NAME}/"
rm -rf "${BACKUP_NAME}/"

echo "Backup completed: ${BACKUP_DIR}/${BACKUP_NAME}.tar.gz"

Method 2: Rsync-based Backup

For incremental backups with rsync:

#!/bin/bash

# Incremental backup with rsync
BACKUP_DIR="/backup/nextcloud"
NEXTCLOUD_DIR="/var/www/nextcloud"
NEXTCLOUD_DATA_DIR="/var/nextcloud/data"

# Create incremental backup
rsync -av --delete "${NEXTCLOUD_DIR}/" "${BACKUP_DIR}/current/nextcloud/"
rsync -av --delete "${NEXTCLOUD_DATA_DIR}/" "${BACKUP_DIR}/current/data/"

# Create daily snapshot
cp -al "${BACKUP_DIR}/current" "${BACKUP_DIR}/daily.$(date +%Y%m%d)"

# Cleanup old snapshots (keep 30 days)
find "${BACKUP_DIR}" -maxdepth 1 -name "daily.*" -mtime +30 -exec rm -rf {} \;

Recovery Procedures

Docker Recovery

Complete system recovery from backup:

# 1. Stop existing containers
cd /var/docker/nextcloud
docker compose down

# 2. Remove existing data (CAUTION!)
sudo rm -rf nextcloud/ mariadb/

# 3. Extract backup
cd /backup/nextcloud
tar -xzf nextcloud_backup_YYYYMMDD_HHMMSS.tar.gz
cd nextcloud_backup_YYYYMMDD_HHMMSS

# 4. Restore configuration files
cp docker-compose.yaml /var/docker/nextcloud/
cp .env /var/docker/nextcloud/

# 5. Extract data
cd /var/docker/nextcloud
tar -xzf /backup/nextcloud/nextcloud_backup_YYYYMMDD_HHMMSS/nextcloud_data.tar.gz

# 6. Start database container first
docker compose up -d mariadb
sleep 30

# 7. Restore database
docker exec -i mariadb mysql -u nextcloud -pYOUR_PASSWORD nextcloud < /backup/nextcloud/nextcloud_backup_YYYYMMDD_HHMMSS/database.sql

# 8. Start all containers
docker compose up -d

# 9. Verify restoration
docker exec -u 33 nextcloud php occ status

Host Installation Recovery

# 1. Stop web server
sudo systemctl stop nginx # or apache2

# 2. Enable maintenance mode (if possible)
sudo -u www-data php /var/www/nextcloud/occ maintenance:mode --on

# 3. Restore database
mysql -u nextcloud -pYOUR_PASSWORD nextcloud < database_backup.sql

# 4. Restore files
tar -xzf nextcloud_install_backup.tar.gz -C /var/www/
tar -xzf nextcloud_data_backup.tar.gz -C /var/nextcloud/

# 5. Fix permissions
sudo chown -R www-data:www-data /var/www/nextcloud/
sudo chown -R www-data:www-data /var/nextcloud/data/

# 6. Start web server
sudo systemctl start nginx

# 7. Disable maintenance mode
sudo -u www-data php /var/www/nextcloud/occ maintenance:mode --off

Best Practices

Backup Strategy

  1. 3-2-1 Rule: 3 copies of data, 2 different media types, 1 offsite
  2. Regular Schedule: Daily incremental, weekly full backups
  3. Test Restores: Regularly test your backup restoration process
  4. Monitor Backups: Set up alerts for backup failures
  5. Document Process: Keep recovery procedures documented and accessible

Security Considerations

# Encrypt backups
gpg --symmetric --cipher-algo AES256 nextcloud_backup.tar.gz

# Secure backup storage permissions
chmod 600 /backup/nextcloud/*
chown backup-user:backup-group /backup/nextcloud/*

# Use dedicated backup user
useradd -r -s /bin/false nextcloud-backup

Storage Considerations

  • Local Backups: Fast recovery, but vulnerable to local disasters
  • Remote Backups: Slower recovery, but protected from local disasters
  • Cloud Storage: Consider services like AWS S3, Google Cloud, or Backblaze B2
# Example: Upload to cloud storage
aws s3 cp nextcloud_backup_${DATE}.tar.gz s3://your-backup-bucket/nextcloud/

# Example: Remote backup with rsync
rsync -avz --delete /backup/nextcloud/ user@backup-server:/backups/nextcloud/

Automated Backup Solutions

Using Cron for Automation

# Edit crontab
crontab -e

# Daily backup at 2 AM
0 2 * * * /usr/local/bin/nextcloud-backup.sh >> /var/log/nextcloud-backup.log 2>&1

# Weekly full backup on Sundays at 1 AM
0 1 * * 0 /usr/local/bin/nextcloud-full-backup.sh >> /var/log/nextcloud-backup.log 2>&1

# Monthly backup cleanup (keep 3 months)
0 3 1 * * find /backup/nextcloud -name "*.tar.gz" -mtime +90 -delete

Backup Monitoring Script

backup-monitor.sh
#!/bin/bash

# Monitor backup completion and size
BACKUP_DIR="/backup/nextcloud"
EXPECTED_MIN_SIZE="100M" # Adjust based on your data size
NOTIFICATION_EMAIL="admin@yourdomain.com"

# Check if today's backup exists
TODAY=$(date +%Y%m%d)
BACKUP_FILE=$(find ${BACKUP_DIR} -name "*${TODAY}*.tar.gz" -type f | head -1)

if [ -z "${BACKUP_FILE}" ]; then
echo "ERROR: No backup found for today (${TODAY})" | mail -s "Nextcloud Backup Missing" ${NOTIFICATION_EMAIL}
exit 1
fi

# Check backup size
BACKUP_SIZE=$(du -h "${BACKUP_FILE}" | cut -f1)
BACKUP_SIZE_BYTES=$(du -b "${BACKUP_FILE}" | cut -f1)
MIN_SIZE_BYTES=$(echo ${EXPECTED_MIN_SIZE} | numfmt --from=iec)

if [ ${BACKUP_SIZE_BYTES} -lt ${MIN_SIZE_BYTES} ]; then
echo "WARNING: Backup size (${BACKUP_SIZE}) is smaller than expected (${EXPECTED_MIN_SIZE})" | mail -s "Nextcloud Backup Size Warning" ${NOTIFICATION_EMAIL}
fi

echo "Backup successful: ${BACKUP_FILE} (${BACKUP_SIZE})"

Troubleshooting

Common Backup Issues

Database Connection Errors:

# Test database connection
docker exec mariadb mysql -u nextcloud -pYOUR_PASSWORD -e "SELECT 1;"

# Check container status
docker ps
docker logs mariadb

Permission Issues:

# Fix Nextcloud permissions
docker exec nextcloud chown -R 33:33 /var/www/html

# Fix backup directory permissions
sudo chown -R $USER:$USER /backup/nextcloud

Disk Space Issues:

# Check disk space
df -h /backup

# Clean old backups
find /backup/nextcloud -name "*.tar.gz" -mtime +30 -delete

# Compress existing backups
gzip /backup/nextcloud/*.sql

Recovery Issues

Database Import Errors:

# Check database encoding
docker exec mariadb mysql -u nextcloud -pYOUR_PASSWORD -e "SHOW VARIABLES LIKE 'character_set%';"

# Import with specific charset
docker exec -i mariadb mysql -u nextcloud -pYOUR_PASSWORD --default-character-set=utf8mb4 nextcloud < database.sql

File Permission Errors:

# Reset Nextcloud permissions (Docker)
docker exec nextcloud chown -R 33:33 /var/www/html
docker exec nextcloud chmod -R 755 /var/www/html

# Reset Nextcloud permissions (Host)
sudo chown -R www-data:www-data /var/www/nextcloud
sudo chmod -R 755 /var/www/nextcloud

Testing Your Backups

Backup Verification Checklist

  1. File Integrity:

    # Test backup archive
    tar -tzf nextcloud_backup.tar.gz > /dev/null && echo "Archive OK" || echo "Archive CORRUPTED"

    # Test database dump
    mysql -u nextcloud -pYOUR_PASSWORD --execute="SET SQL_MODE='NO_AUTO_VALUE_ON_ZERO'; SOURCE database.sql;" 2>/dev/null && echo "Database OK" || echo "Database CORRUPTED"
  2. Restoration Test:

    • Set up a test environment
    • Restore from backup
    • Verify all functionality works
    • Test user login and file access
  3. Regular Testing Schedule:

    • Monthly: Quick verification tests
    • Quarterly: Full restoration tests
    • Annually: Disaster recovery simulation

Conclusion

A robust backup strategy is essential for any Nextcloud installation. Whether you're running Docker containers or a host installation, regular automated backups combined with tested recovery procedures will protect your valuable data.

Remember to:

  • Test your backups regularly
  • Keep multiple backup copies
  • Store backups in different locations
  • Document your recovery procedures
  • Monitor backup completion and file integrity

For additional help with backup and recovery procedures, visit our Discord or leave a comment below.

Buy me a beer

Changelog

fix(nextcloud-backup): address Copilot review - strip .env quotes, grep -E portability, cleanup staging on container failure, check maintenance mode --off
fix(nextcloud-backup): use fuzzy container lookup to handle Docker Compose project-name prefixes
docs(nextcloud): rewrite backup script with .env auto-detection and descriptive error messages
Add comprehensive Nextcloud backup documentation


💬 Discord Community Chat

Join the conversation! Comments here sync with our Discord community.

💬 Recent Comments

Loading comments...