1151 lines
31 KiB
Markdown
1151 lines
31 KiB
Markdown
---
|
|
title: Nextcloud Backup
|
|
description: Native + Kopia
|
|
published: true
|
|
date: 2026-02-18T04:40:14.455Z
|
|
tags:
|
|
editor: markdown
|
|
dateCreated: 2026-02-14T23:52:25.405Z
|
|
---
|
|
|
|
---
|
|
title: Nextcloud AIO Backup and Recovery Guide
|
|
description: Comprehensive backup and recovery procedures for Nextcloud All-in-One using native BorgBackup and Kopia offsite storage
|
|
published: true
|
|
date: 2026-02-17
|
|
tags: nextcloud, backup, borgbackup, kopia, docker, aio
|
|
editor: markdown
|
|
---
|
|
|
|
# Nextcloud AIO Backup and Recovery Guide
|
|
|
|
## Overview
|
|
|
|
This document provides comprehensive backup and recovery procedures for Nextcloud All-in-One (AIO). Nextcloud AIO includes a **built-in BorgBackup solution** that runs daily automated backups. We enhance this with Kopia for offsite storage in vaults, following the same two-tier approach used for Mailcow and Immich.
|
|
|
|
## Quick Reference
|
|
|
|
### Common Backup Commands
|
|
|
|
```bash
|
|
# Run Kopia snapshot script (snapshots AIO's backups)
|
|
/opt/scripts/backup-nextcloud.sh
|
|
|
|
# Manually trigger AIO backup via web interface
|
|
# Navigate to: https://your-server:8080 → Backup section → Create Backup
|
|
|
|
# List Kopia snapshots
|
|
kopia snapshot list --tags nextcloud
|
|
|
|
# View backup logs
|
|
tail -f /var/log/nextcloud-backup.log
|
|
|
|
# Check AIO backup status
|
|
docker exec -it nextcloud-aio-mastercontainer ls -lh /mnt/docker-aio-config/data/borg/
|
|
```
|
|
|
|
### Common Restore Commands
|
|
|
|
```bash
|
|
# Restore using AIO's built-in interface (RECOMMENDED)
|
|
# Navigate to: https://your-server:8080 → Backup section → Restore
|
|
|
|
# Restore from Kopia to new server
|
|
kopia snapshot list --tags nextcloud
|
|
kopia restore <snapshot-id> /opt/nextcloud-backups/
|
|
|
|
# Check container status after restore
|
|
docker ps | grep nextcloud
|
|
docker logs -f nextcloud-aio-mastercontainer
|
|
```
|
|
|
|
## Critical Components to Backup
|
|
|
|
### 1. Nextcloud AIO BorgBackup Repository
|
|
- **Location**: Docker volume `nextcloud_aio_mastercontainer` → `/mnt/docker-aio-config/data/borg/`
|
|
- **Contains**:
|
|
- Complete PostgreSQL database
|
|
- All user files and data
|
|
- Nextcloud configuration
|
|
- Apps and their data
|
|
- **Importance**: This is Nextcloud AIO's primary backup - contains everything needed for restore
|
|
- **Encryption**: Encrypted with BorgBackup password
|
|
|
|
### 2. Nextcloud Data Directory
|
|
- **Location**: `/srv/NextCloud-AIO` (per NEXTCLOUD_DATADIR setting)
|
|
- **Purpose**: User files, photos, documents
|
|
- **Note**: Already included in AIO BorgBackup, but can be backed up separately with Kopia
|
|
|
|
### 3. AIO Mastercontainer Volume
|
|
- **Volume**: `nextcloud_aio_mastercontainer`
|
|
- **Contains**: AIO configuration, certificates, Borg repository
|
|
- **Critical**: Required to restore AIO itself
|
|
|
|
### 4. Docker Compose Configuration
|
|
- **Location**: `/opt/nextcloud/docker-compose.yml`
|
|
- **Purpose**: Container definitions, network settings, environment variables
|
|
- **Importance**: Needed to recreate the AIO setup
|
|
|
|
### 5. Backup Credentials
|
|
- **BorgBackup Password**: `0c038ada7a620e59802f43422b6fea409b46bab8821be6d3`
|
|
- **Storage**: Store securely in password manager
|
|
- **Critical**: Required for restoring from Borg backups
|
|
|
|
## Backup Strategy
|
|
|
|
### Two-Tier Backup Approach
|
|
|
|
We use a **two-tier approach** combining Nextcloud AIO's native BorgBackup with Kopia for offsite storage:
|
|
|
|
1. **Tier 1 (Nextcloud AIO Native)**: BorgBackup creates deduplicated, encrypted backups daily at 02:00
|
|
2. **Tier 2 (Offsite)**: Kopia snapshots the Borg repository at 03:00 and syncs to vaults
|
|
|
|
#### Why This Approach?
|
|
|
|
- **Best of both worlds**: AIO's BorgBackup is Nextcloud-aware and handles everything correctly, Kopia provides offsite protection
|
|
- **Native restore**: Use AIO's built-in restore interface (easiest, most reliable)
|
|
- **Disaster recovery**: Full system restore from Kopia backups on new server
|
|
- **Deduplication at two levels**: Borg deduplicates within Nextcloud data, Kopia deduplicates across backups
|
|
- **Proven strategy**: Same approach used for Mailcow and Immich
|
|
|
|
#### Backup Schedule
|
|
- **02:00** - AIO's daily BorgBackup runs automatically
|
|
- **03:00** - Kopia script snapshots the completed Borg repository
|
|
- **Retention (AIO Borg)**: `--keep-within=7d --keep-weekly=4 --keep-monthly=6`
|
|
- **Retention (Kopia/Offsite)**: 30 daily, 12 weekly, 12 monthly
|
|
|
|
### Nextcloud AIO Native Backup (BorgBackup)
|
|
|
|
Nextcloud AIO includes an integrated BorgBackup solution that:
|
|
- Backs up PostgreSQL database (hot backup, no downtime)
|
|
- Backs up all user files and data
|
|
- Backs up Nextcloud configuration and apps
|
|
- Provides deduplication and compression
|
|
- Runs on daily schedule (configured in AIO interface)
|
|
- Includes built-in restore interface
|
|
|
|
**Key Features:**
|
|
- **Deduplication**: Only stores changed blocks (very efficient)
|
|
- **Compression**: Reduces backup size significantly
|
|
- **Encryption**: Backups are encrypted with password
|
|
- **Incremental**: Only backs up changes after first backup
|
|
- **Web UI**: Manage backups through AIO's admin interface
|
|
|
|
**BorgBackup Location:**
|
|
- Inside mastercontainer volume: `/mnt/docker-aio-config/data/borg/`
|
|
- On host: `/var/lib/docker/volumes/nextcloud_aio_mastercontainer/_data/data/borg/`
|
|
|
|
## Setting Up Nextcloud AIO Backups
|
|
|
|
### Prerequisites
|
|
|
|
#### Connect to Kopia Repository
|
|
|
|
```bash
|
|
sudo kopia repository connect server \
|
|
--url=https://192.168.5.10:51516 \
|
|
--override-username=admin \
|
|
--server-cert-fingerprint=696a4999f594b5273a174fd7cab677d8dd1628f9b9d27e557daa87103ee064b2
|
|
```
|
|
|
|
> **Note on Multiple Kopia Repositories**: The backup script handles multiple Kopia repositories by explicitly connecting to the Nextcloud-specific repository at the start of each backup. To use a different repository, edit the variables in `/opt/scripts/backup-nextcloud.sh`.
|
|
|
|
### Step 1: Configure AIO's Daily Backup
|
|
|
|
First, configure Nextcloud AIO's built-in backup system:
|
|
|
|
1. **Access AIO Admin Interface**:
|
|
```
|
|
https://your-server:8080
|
|
```
|
|
|
|
2. **Navigate to Backup Section** in the AIO interface
|
|
|
|
3. **Configure Daily Backup**:
|
|
- Set **Backup time**: `02:00` (2 AM)
|
|
- Enable **Daily backup**
|
|
- Optionally enable **Automatic updates after backup**
|
|
- Optionally enable **Success notification**
|
|
|
|
4. **Verify Backup Location**:
|
|
The backup location should be set to (default):
|
|
```
|
|
/mnt/docker-aio-config/data/borg
|
|
```
|
|
|
|
5. **Trigger First Backup** manually via AIO interface to verify it works:
|
|
- Click "Create Backup" button
|
|
- Wait for completion (may take a while on first run)
|
|
- Verify success in the interface
|
|
|
|
6. **Verify Backup Exists**:
|
|
```bash
|
|
docker exec nextcloud-aio-mastercontainer ls -lh /mnt/docker-aio-config/data/borg/
|
|
```
|
|
|
|
### Step 2: Configure Local Backup Directory
|
|
|
|
Create the backup directory for Kopia metadata:
|
|
|
|
```bash
|
|
sudo mkdir -p /opt/nextcloud-backups
|
|
sudo chown -R root:root /opt/nextcloud-backups
|
|
sudo chmod 755 /opt/nextcloud-backups
|
|
```
|
|
|
|
### Step 3: Install Kopia Backup Script
|
|
|
|
```bash
|
|
# Create scripts directory if not exists
|
|
sudo mkdir -p /opt/scripts
|
|
|
|
# Copy the backup script
|
|
sudo cp backup-nextcloud.sh /opt/scripts/
|
|
sudo chmod +x /opt/scripts/backup-nextcloud.sh
|
|
```
|
|
|
|
### Step 4: Configure Backup Script
|
|
|
|
Edit `/opt/scripts/backup-nextcloud.sh` and verify these settings:
|
|
|
|
```bash
|
|
BACKUP_DIR="/opt/nextcloud-backups" # Local backup storage
|
|
KEEP_DAYS=7 # Keep 7 days locally
|
|
NEXTCLOUD_DIR="/opt/nextcloud" # Your Nextcloud compose location
|
|
DATADIR="/srv/NextCloud-AIO" # Your NEXTCLOUD_DATADIR
|
|
KOPIA_SERVER_URL="https://192.168.5.10:51516" # Your Kopia server
|
|
KOPIA_USERNAME="admin"
|
|
KOPIA_FINGERPRINT="696a4999..."
|
|
```
|
|
|
|
### Step 5: Test Manual Backup
|
|
|
|
Run your first Kopia snapshot manually:
|
|
|
|
```bash
|
|
sudo /opt/scripts/backup-nextcloud.sh
|
|
```
|
|
|
|
Expected output:
|
|
```
|
|
========================================
|
|
Starting Nextcloud Kopia snapshot process
|
|
Note: AIO daily backup runs at 02:00, this script snapshots it
|
|
========================================
|
|
[timestamp] Connecting to Kopia repository...
|
|
[timestamp] Kopia repository connected successfully
|
|
[timestamp] Checking Nextcloud AIO status...
|
|
[timestamp] Mastercontainer is running
|
|
[timestamp] Verifying AIO Borg backups...
|
|
[timestamp] Found Borg backup repository at: /mnt/docker-aio-config/data/borg
|
|
[timestamp] Backing up AIO mastercontainer volume...
|
|
[timestamp] Mastercontainer volume backup completed (5.2G)
|
|
[timestamp] Creating Kopia snapshots for offsite storage
|
|
...
|
|
✓ AIO Borg backups verified
|
|
✓ Mastercontainer volume backed up (5.2G)
|
|
✓ Kopia snapshots created for offsite storage
|
|
========================================
|
|
```
|
|
|
|
Verify the backup:
|
|
```bash
|
|
# Check local backup
|
|
ls -lh /opt/nextcloud-backups/
|
|
cat /opt/nextcloud-backups/nextcloud-*/manifest.txt
|
|
|
|
# Check Kopia snapshots
|
|
kopia snapshot list --tags nextcloud
|
|
|
|
# Check AIO Borg backups
|
|
docker exec nextcloud-aio-mastercontainer ls -lh /mnt/docker-aio-config/data/borg/
|
|
```
|
|
|
|
### Step 6: Automated Backup with Cron
|
|
|
|
**Important Timing**: Schedule this AFTER AIO's built-in backup completes.
|
|
- AIO backup: **02:00** (configured in AIO interface)
|
|
- Kopia script: **03:00** (snapshots the completed Borg backup)
|
|
|
|
Add to root's crontab:
|
|
|
|
```bash
|
|
sudo crontab -e
|
|
```
|
|
|
|
Add this line for daily backups at 3 AM:
|
|
```
|
|
0 3 * * * /opt/scripts/backup-nextcloud.sh 2>&1 | logger -t nextcloud-backup
|
|
```
|
|
|
|
Alternative schedules:
|
|
|
|
**Twice daily (3 AM and 3 PM):**
|
|
```
|
|
0 3,15 * * * /opt/scripts/backup-nextcloud.sh 2>&1 | logger -t nextcloud-backup
|
|
```
|
|
|
|
**After AIO backup completes (2 AM AIO + 1 hour buffer):**
|
|
```
|
|
0 3 * * * /opt/scripts/backup-nextcloud.sh 2>&1 | logger -t nextcloud-backup
|
|
```
|
|
|
|
### Step 7: Configure Kopia Retention Policy
|
|
|
|
Set retention for Nextcloud snapshots:
|
|
|
|
```bash
|
|
kopia policy set /opt/nextcloud-backups \
|
|
--keep-latest 30 \
|
|
--keep-daily 30 \
|
|
--keep-weekly 12 \
|
|
--keep-monthly 12
|
|
|
|
kopia policy set /opt/nextcloud \
|
|
--keep-latest 7 \
|
|
--keep-daily 7
|
|
|
|
# If backing up datadir directly (and it's small enough)
|
|
kopia policy set /srv/NextCloud-AIO \
|
|
--keep-latest 7 \
|
|
--keep-daily 7
|
|
```
|
|
|
|
## Backup Validation
|
|
|
|
### Regular Verification
|
|
|
|
Perform these checks monthly to ensure backups are working:
|
|
|
|
#### Test 1: Verify AIO Borg Backups Exist
|
|
|
|
```bash
|
|
# List Borg archives inside container
|
|
docker exec nextcloud-aio-mastercontainer \
|
|
borg list /mnt/docker-aio-config/data/borg/borgbackup
|
|
|
|
# Expected output: List of backup archives with dates
|
|
```
|
|
|
|
#### Test 2: Check Borg Backup Integrity
|
|
|
|
```bash
|
|
# Run Borg check (non-destructive)
|
|
docker exec nextcloud-aio-mastercontainer \
|
|
borg check /mnt/docker-aio-config/data/borg/borgbackup
|
|
|
|
# Expected output: Repository and archive checks passing
|
|
```
|
|
|
|
#### Test 3: Verify Local Kopia Backups
|
|
|
|
```bash
|
|
# List recent local backups
|
|
ls -lth /opt/nextcloud-backups/ | head -5
|
|
|
|
# Check most recent backup
|
|
LATEST=$(ls -td /opt/nextcloud-backups/nextcloud-* | head -1)
|
|
cat "${LATEST}/manifest.txt"
|
|
```
|
|
|
|
#### Test 4: Verify Kopia Snapshots
|
|
|
|
```bash
|
|
# List Kopia snapshots
|
|
kopia snapshot list --tags nextcloud
|
|
|
|
# Verify snapshot content (without restoring)
|
|
kopia snapshot list --show-identical
|
|
|
|
# Check Kopia repository status
|
|
kopia repository status
|
|
```
|
|
|
|
#### Test 5: Verify Backup Encryption
|
|
|
|
```bash
|
|
# The BorgBackup password should be required for restore
|
|
# Test by attempting to list archives (should require password)
|
|
|
|
docker exec -it nextcloud-aio-mastercontainer bash
|
|
export BORG_PASSPHRASE="0c038ada7a620e59802f43422b6fea409b46bab8821be6d3"
|
|
borg list /mnt/docker-aio-config/data/borg/borgbackup
|
|
exit
|
|
```
|
|
|
|
### Backup Monitoring Script
|
|
|
|
Create `/opt/scripts/check-nextcloud-backup.sh`:
|
|
|
|
```bash
|
|
#!/bin/bash
|
|
|
|
LOG_PREFIX="[Nextcloud Backup Check]"
|
|
|
|
# Check 1: AIO Borg backups
|
|
echo "$LOG_PREFIX Checking AIO Borg backups..."
|
|
BORG_COUNT=$(docker exec nextcloud-aio-mastercontainer \
|
|
find /mnt/docker-aio-config/data/borg -type d -maxdepth 2 2>/dev/null | wc -l)
|
|
|
|
if [ "$BORG_COUNT" -gt 0 ]; then
|
|
echo "$LOG_PREFIX ✓ AIO has $BORG_COUNT Borg backup items"
|
|
else
|
|
echo "$LOG_PREFIX ✗ WARNING: No Borg backups found!"
|
|
exit 1
|
|
fi
|
|
|
|
# Check 2: Local backups
|
|
echo "$LOG_PREFIX Checking local backups..."
|
|
LAST_BACKUP=$(ls -td /opt/nextcloud-backups/nextcloud-* 2>/dev/null | head -1)
|
|
|
|
if [ -z "$LAST_BACKUP" ]; then
|
|
echo "$LOG_PREFIX ✗ WARNING: No local backups found!"
|
|
exit 1
|
|
fi
|
|
|
|
BACKUP_DATE=$(basename "$LAST_BACKUP" | sed 's/nextcloud-//')
|
|
BACKUP_EPOCH=$(date -d "${BACKUP_DATE:0:8} ${BACKUP_DATE:9:2}:${BACKUP_DATE:11:2}:${BACKUP_DATE:13:2}" +%s 2>/dev/null)
|
|
NOW=$(date +%s)
|
|
AGE_HOURS=$(( ($NOW - $BACKUP_EPOCH) / 3600 ))
|
|
|
|
if [ $AGE_HOURS -gt 26 ]; then
|
|
echo "$LOG_PREFIX ✗ WARNING: Last backup is $AGE_HOURS hours old"
|
|
exit 1
|
|
else
|
|
echo "$LOG_PREFIX ✓ Last backup: $AGE_HOURS hours ago"
|
|
BACKUP_SIZE=$(du -sh "$LAST_BACKUP" 2>/dev/null | cut -f1)
|
|
echo "$LOG_PREFIX Size: $BACKUP_SIZE"
|
|
fi
|
|
|
|
# Check 3: Kopia snapshots
|
|
echo "$LOG_PREFIX Checking Kopia snapshots..."
|
|
KOPIA_COUNT=$(kopia snapshot list --tags nextcloud --json 2>/dev/null | jq '. | length' 2>/dev/null)
|
|
|
|
if [ -n "$KOPIA_COUNT" ] && [ "$KOPIA_COUNT" -gt 0 ]; then
|
|
echo "$LOG_PREFIX ✓ Kopia has $KOPIA_COUNT snapshots"
|
|
KOPIA_LAST=$(kopia snapshot list --tags nextcloud --json 2>/dev/null | jq -r '.[0].startTime' 2>/dev/null)
|
|
echo "$LOG_PREFIX Latest: $KOPIA_LAST"
|
|
else
|
|
echo "$LOG_PREFIX ✗ WARNING: Cannot verify Kopia snapshots"
|
|
exit 1
|
|
fi
|
|
|
|
echo "$LOG_PREFIX ========================================="
|
|
echo "$LOG_PREFIX All backup checks passed!"
|
|
echo "$LOG_PREFIX ========================================="
|
|
```
|
|
|
|
Make executable and add to cron:
|
|
```bash
|
|
chmod +x /opt/scripts/check-nextcloud-backup.sh
|
|
|
|
# Add to crontab (check daily at 8 AM)
|
|
sudo crontab -e
|
|
0 8 * * * /opt/scripts/check-nextcloud-backup.sh | logger -t nextcloud-backup-check
|
|
```
|
|
|
|
### Test Restore (Non-Production)
|
|
|
|
Perform a test restore in a non-production environment quarterly:
|
|
|
|
1. **Provision test server** with same OS
|
|
2. **Install Docker** and Kopia
|
|
3. **Restore from Kopia** following disaster recovery steps below
|
|
4. **Verify Nextcloud** works correctly
|
|
5. **Document any issues** encountered
|
|
6. **Destroy test environment**
|
|
|
|
## Recovery Procedures
|
|
|
|
### Understanding Two Recovery Methods
|
|
|
|
We have **two restore methods** depending on the scenario:
|
|
|
|
1. **AIO Native Restore** (Preferred): Use AIO's built-in restore interface
|
|
2. **Kopia Full Restore**: For complete disaster recovery to a new server
|
|
|
|
### Method 1: AIO Native Restore (Recommended)
|
|
|
|
Use this method when:
|
|
- Restoring on the same server
|
|
- AIO is still functional
|
|
- You have AIO Borg backups available
|
|
|
|
This is the **easiest and most reliable** method for Nextcloud AIO.
|
|
|
|
#### Via AIO Web Interface (Easiest)
|
|
|
|
1. **Access AIO Admin Interface**:
|
|
```
|
|
https://your-server:8080
|
|
```
|
|
|
|
2. **Navigate to Backup Section**
|
|
|
|
3. **Select Restore**
|
|
|
|
4. **Enter BorgBackup Password**:
|
|
```
|
|
0c038ada7a620e59802f43422b6fea409b46bab8821be6d3
|
|
```
|
|
|
|
5. **Choose Backup Date** from available Borg backups
|
|
|
|
6. **Confirm Restore**
|
|
- AIO will:
|
|
- Stop Nextcloud containers
|
|
- Restore database
|
|
- Restore all files
|
|
- Restore configuration
|
|
- Restart containers
|
|
|
|
7. **Verify** Nextcloud is working after restore:
|
|
- Access web interface
|
|
- Check files are accessible
|
|
- Verify user logins work
|
|
|
|
#### Via Command Line (Advanced)
|
|
|
|
If you need to restore from Borg backup directly:
|
|
|
|
```bash
|
|
# Enter the mastercontainer
|
|
docker exec -it nextcloud-aio-mastercontainer bash
|
|
|
|
# Set Borg password
|
|
export BORG_PASSPHRASE="0c038ada7a620e59802f43422b6fea409b46bab8821be6d3"
|
|
|
|
# List available backups
|
|
borg list /mnt/docker-aio-config/data/borg/borgbackup
|
|
|
|
# Extract specific backup (example - adjust archive name)
|
|
borg extract /mnt/docker-aio-config/data/borg/borgbackup::20260217-020001
|
|
|
|
# Exit container
|
|
exit
|
|
```
|
|
|
|
> **Note**: Using AIO's web interface is much safer and handles all the container orchestration automatically.
|
|
|
|
### Method 2: Complete Server Rebuild (Kopia Restore)
|
|
|
|
Use this when recovering to a completely new server or when AIO is completely lost.
|
|
|
|
#### Step 1: Prepare New Server
|
|
|
|
```bash
|
|
# Update system
|
|
sudo apt update && sudo apt upgrade -y
|
|
|
|
# Install Docker
|
|
curl -fsSL https://get.docker.com | sh
|
|
sudo systemctl enable docker
|
|
sudo systemctl start docker
|
|
|
|
# Install Docker Compose
|
|
sudo apt install docker-compose-plugin -y
|
|
|
|
# Install Kopia
|
|
curl -s https://kopia.io/signing-key | sudo gpg --dearmor -o /usr/share/keyrings/kopia-keyring.gpg
|
|
echo "deb [signed-by=/usr/share/keyrings/kopia-keyring.gpg] https://packages.kopia.io/apt/ stable main" | sudo tee /etc/apt/sources.list.d/kopia.list
|
|
sudo apt update
|
|
sudo apt install kopia -y
|
|
|
|
# Create directory structure
|
|
sudo mkdir -p /opt/nextcloud
|
|
sudo mkdir -p /opt/nextcloud-backups
|
|
sudo mkdir -p /srv/NextCloud-AIO
|
|
```
|
|
|
|
#### Step 2: Connect to Kopia Repository
|
|
|
|
```bash
|
|
# Connect to your offsite vault
|
|
sudo kopia repository connect server \
|
|
--url=https://192.168.5.10:51516 \
|
|
--override-username=admin \
|
|
--server-cert-fingerprint=696a4999f594b5273a174fd7cab677d8dd1628f9b9d27e557daa87103ee064b2
|
|
|
|
# Verify connection
|
|
kopia repository status
|
|
|
|
# List available snapshots
|
|
kopia snapshot list --tags nextcloud
|
|
```
|
|
|
|
#### Step 3: Restore Configuration
|
|
|
|
```bash
|
|
# Find and restore the config snapshot
|
|
kopia snapshot list --tags config
|
|
|
|
# Restore to the Nextcloud directory
|
|
kopia restore <config-snapshot-id> /opt/nextcloud/
|
|
|
|
# Verify critical files
|
|
ls -la /opt/nextcloud/docker-compose.yml
|
|
```
|
|
|
|
#### Step 4: Restore AIO Mastercontainer Volume
|
|
|
|
```bash
|
|
# Find the backup with mastercontainer
|
|
kopia snapshot list --tags mastercontainer
|
|
|
|
# Restore the most recent backup
|
|
kopia restore <snapshot-id> /opt/nextcloud-backups/
|
|
|
|
# Find the most recent backup directory
|
|
LATEST_BACKUP=$(ls -td /opt/nextcloud-backups/nextcloud-* | head -1)
|
|
echo "Restoring from: $LATEST_BACKUP"
|
|
|
|
# Create the Docker volume
|
|
docker volume create nextcloud_aio_mastercontainer
|
|
|
|
# Extract mastercontainer volume backup
|
|
docker run --rm \
|
|
-v nextcloud_aio_mastercontainer:/target \
|
|
-v "${LATEST_BACKUP}":/backup:ro \
|
|
alpine tar -xzf /backup/aio-mastercontainer.tar.gz -C /target
|
|
|
|
echo "Mastercontainer volume restored"
|
|
```
|
|
|
|
#### Step 5: Start Nextcloud AIO
|
|
|
|
```bash
|
|
cd /opt/nextcloud
|
|
|
|
# Create external network if needed
|
|
docker network create netgrimoire
|
|
|
|
# Start mastercontainer
|
|
docker compose up -d
|
|
|
|
# Monitor logs
|
|
docker compose logs -f
|
|
```
|
|
|
|
#### Step 6: Access AIO and Restore from Borg
|
|
|
|
1. **Wait for mastercontainer to initialize** (1-2 minutes)
|
|
|
|
2. **Access AIO Interface**:
|
|
```
|
|
https://new-server-ip:8080
|
|
```
|
|
|
|
3. **Navigate to Backup Section**
|
|
|
|
4. **Select Restore**
|
|
|
|
5. **Enter BorgBackup Password**:
|
|
```
|
|
0c038ada7a620e59802f43422b6fea409b46bab8821be6d3
|
|
```
|
|
|
|
6. **Choose backup date** and restore
|
|
|
|
7. **Wait for restore to complete** (may take significant time depending on data size)
|
|
|
|
#### Step 7: Post-Restore Verification
|
|
|
|
```bash
|
|
# Check all containers are running
|
|
docker ps | grep nextcloud
|
|
|
|
# Expected containers:
|
|
# - nextcloud-aio-mastercontainer
|
|
# - nextcloud-aio-apache
|
|
# - nextcloud-aio-nextcloud
|
|
# - nextcloud-aio-database
|
|
# - nextcloud-aio-redis
|
|
# - nextcloud-aio-imaginary
|
|
# - nextcloud-aio-fulltextsearch (if enabled)
|
|
# - nextcloud-aio-talk (if enabled)
|
|
|
|
# Check Nextcloud is accessible via Apache
|
|
curl -I http://localhost:11000
|
|
|
|
# Access web interface
|
|
# https://your-server-domain
|
|
|
|
# Verify:
|
|
# - Login works
|
|
# - Files are accessible
|
|
# - Apps are functioning
|
|
# - Sharing works
|
|
# - Uploads work
|
|
```
|
|
|
|
### Scenario 2: Restore Specific User's Files
|
|
|
|
To restore a single user's files without affecting others:
|
|
|
|
#### Option A: Via AIO Web Interface (Safest)
|
|
|
|
1. Use AIO's restore to restore to a specific point in time
|
|
2. Users can access previous versions via Nextcloud's version history
|
|
|
|
#### Option B: Extract from Borg Backup
|
|
|
|
```bash
|
|
# Enter mastercontainer
|
|
docker exec -it nextcloud-aio-mastercontainer bash
|
|
|
|
# Set Borg password
|
|
export BORG_PASSPHRASE="0c038ada7a620e59802f43422b6fea409b46bab8821be6d3"
|
|
|
|
# List available backups
|
|
borg list /mnt/docker-aio-config/data/borg/borgbackup
|
|
|
|
# Mount a specific backup
|
|
mkdir -p /tmp/borg-mount
|
|
borg mount /mnt/docker-aio-config/data/borg/borgbackup::<archive-name> /tmp/borg-mount
|
|
|
|
# Navigate to user's files
|
|
cd /tmp/borg-mount/nextcloud_aio_nextcloud_data/
|
|
|
|
# Find the user's directory
|
|
ls -la
|
|
|
|
# Copy specific files out (example)
|
|
cp -r /tmp/borg-mount/nextcloud_aio_nextcloud_data/<username>/ /recovery/
|
|
|
|
# Unmount
|
|
borg umount /tmp/borg-mount
|
|
exit
|
|
```
|
|
|
|
#### Option C: Using Kopia Mount
|
|
|
|
```bash
|
|
# Mount Kopia snapshot
|
|
kopia snapshot list --tags datadir
|
|
mkdir -p /mnt/kopia-nextcloud
|
|
kopia mount <snapshot-id> /mnt/kopia-nextcloud &
|
|
|
|
# Find user's files
|
|
USER="username"
|
|
ls /mnt/kopia-nextcloud/${USER}/files/
|
|
|
|
# Copy files back
|
|
rsync -av /mnt/kopia-nextcloud/${USER}/files/ \
|
|
/srv/NextCloud-AIO/${USER}/files/
|
|
|
|
# Unmount
|
|
kopia unmount /mnt/kopia-nextcloud
|
|
|
|
# Rescan files in Nextcloud
|
|
docker exec -u www-data nextcloud-aio-nextcloud \
|
|
php occ files:scan ${USER}
|
|
```
|
|
|
|
### Scenario 3: Rollback After Failed Update
|
|
|
|
If a Nextcloud update breaks your installation:
|
|
|
|
1. **Access AIO Interface**: `https://your-server:8080`
|
|
|
|
2. **Navigate to Backup Section**
|
|
|
|
3. **Select Restore**
|
|
|
|
4. **Enter password**: `0c038ada7a620e59802f43422b6fea409b46bab8821be6d3`
|
|
|
|
5. **Choose backup** from before the update
|
|
|
|
6. **Restore and verify**
|
|
|
|
7. **Disable auto-updates** in AIO until issue is resolved
|
|
|
|
### Scenario 4: Database-Only Recovery
|
|
|
|
If only the database is corrupted but files are intact:
|
|
|
|
**Via AIO Restore (Recommended):**
|
|
1. Use AIO's restore feature
|
|
2. It will restore the complete state including database
|
|
|
|
**Note**: AIO's BorgBackup stores everything together, so you cannot easily restore just the database. A full restore is safer and ensures consistency.
|
|
|
|
## Disaster Recovery Checklist
|
|
|
|
When disaster strikes, follow this checklist:
|
|
|
|
- [ ] Confirm scope of failure (server down, storage failure, data corruption)
|
|
- [ ] Gather server information (hostname, IP, domain configuration)
|
|
- [ ] Retrieve BorgBackup password from secure storage
|
|
- [ ] Access offsite Kopia repository
|
|
- [ ] Provision new server (if needed) with Docker and Kopia
|
|
- [ ] Connect to Kopia repository
|
|
- [ ] Restore docker-compose configuration
|
|
- [ ] Restore AIO mastercontainer volume
|
|
- [ ] Start AIO mastercontainer
|
|
- [ ] Use AIO's restore interface with BorgBackup password
|
|
- [ ] Verify web interface accessible
|
|
- [ ] Test file access and sharing
|
|
- [ ] Verify user logins work
|
|
- [ ] Check all apps are functioning
|
|
- [ ] Update DNS if server IP changed
|
|
- [ ] Document issues and lessons learned
|
|
- [ ] Update this guide based on experience
|
|
|
|
## Important Notes
|
|
|
|
### 1. Backup Schedule Coordination
|
|
|
|
- **AIO backup**: 02:00 (configured in AIO interface)
|
|
- **Kopia script**: 03:00 (must run AFTER AIO backup completes)
|
|
- Ensure sufficient time gap for large backups
|
|
|
|
### 2. BorgBackup Password Security
|
|
|
|
- **Password**: `0c038ada7a620e59802f43422b6fea409b46bab8821be6d3`
|
|
- **Storage**: Keep in password manager (LastPass, 1Password, etc.)
|
|
- **Backup**: Print and store in safe location
|
|
- **Critical**: Without this password, Borg backups cannot be restored
|
|
|
|
### 3. Storage Requirements
|
|
|
|
BorgBackup is deduplicated but can still be large:
|
|
- Borg repository: ~1.5x your data size initially
|
|
- Grows with retention policy (7 days + 4 weeks + 6 months)
|
|
- Kopia adds minimal overhead due to deduplication
|
|
- Monitor disk space regularly
|
|
|
|
### 4. Network Configuration
|
|
|
|
Your setup uses:
|
|
- External network: `netgrimoire`
|
|
- Custom Apache port: `11000`
|
|
- AIO admin port: `8080`
|
|
- Ensure these are documented for restore
|
|
|
|
### 5. Testing
|
|
|
|
- Test recovery procedures quarterly in lab environment
|
|
- Verify backups monthly with validation scripts
|
|
- Keep printed copy of this guide offsite
|
|
|
|
### 6. Updates
|
|
|
|
- AIO can auto-update containers after successful backup
|
|
- This is configured in the daily backup settings
|
|
- Ensure backups run BEFORE updates
|
|
|
|
### 7. Performance Considerations
|
|
|
|
First backup will be slow (full copy):
|
|
- Subsequent backups are incremental (much faster)
|
|
- Borg deduplication improves over time
|
|
- Large files (videos) take longer
|
|
|
|
## Backup Architecture Notes
|
|
|
|
### Why Two Backup Layers?
|
|
|
|
**Nextcloud AIO BorgBackup** (Tier 1):
|
|
- ✅ Nextcloud-aware (knows how to backup everything correctly)
|
|
- ✅ Built-in restore interface (easiest to use)
|
|
- ✅ Deduplication and compression
|
|
- ✅ Encrypted with password
|
|
- ✅ Incremental backups (efficient)
|
|
- ❌ Single location (inside Docker volume)
|
|
- ❌ No offsite replication built-in
|
|
|
|
**Kopia Snapshots** (Tier 2):
|
|
- ✅ Offsite protection in vaults
|
|
- ✅ Additional deduplication layer
|
|
- ✅ Point-in-time recovery
|
|
- ✅ Disaster recovery to new infrastructure
|
|
- ✅ Independent of Nextcloud/Docker state
|
|
- ❌ Less Nextcloud-aware
|
|
- ❌ More complex restore process
|
|
|
|
### Storage Efficiency
|
|
|
|
For a 200GB Nextcloud instance:
|
|
|
|
**BorgBackup (Tier 1):**
|
|
- First backup: ~200GB
|
|
- Daily incremental: ~2-5GB (only changes)
|
|
- With retention policy: ~250GB total
|
|
|
|
**Kopia (Tier 2) backing up mastercontainer:**
|
|
- First snapshot: ~250GB
|
|
- Daily changes: ~5-10GB (only changed data in Borg repo)
|
|
- Much smaller than backing up raw data repeatedly
|
|
|
|
**Combined savings**: Borg handles Nextcloud-level deduplication, Kopia handles backup-to-backup deduplication
|
|
|
|
### Deduplication Layers
|
|
|
|
1. **Nextcloud level**: File versioning and deleted file retention
|
|
2. **Borg level**: Block-level deduplication within Nextcloud data
|
|
3. **Kopia level**: File-level deduplication of mastercontainer volume
|
|
|
|
## Troubleshooting
|
|
|
|
### "Cannot access AIO interface"
|
|
|
|
**Symptoms**: Cannot connect to port 8080
|
|
|
|
**Solutions**:
|
|
```bash
|
|
# Check mastercontainer is running
|
|
docker ps | grep nextcloud-aio-mastercontainer
|
|
|
|
# Check logs
|
|
docker logs nextcloud-aio-mastercontainer
|
|
|
|
# Restart mastercontainer
|
|
cd /opt/nextcloud
|
|
docker compose restart
|
|
|
|
# Check firewall
|
|
sudo ufw status
|
|
sudo ufw allow 8080/tcp
|
|
```
|
|
|
|
### "Borg backup fails"
|
|
|
|
**Symptoms**: AIO reports backup failure
|
|
|
|
**Solutions**:
|
|
```bash
|
|
# Check disk space
|
|
df -h
|
|
|
|
# Check Borg repository integrity
|
|
docker exec nextcloud-aio-mastercontainer bash
|
|
export BORG_PASSPHRASE="0c038ada7a620e59802f43422b6fea409b46bab8821be6d3"
|
|
borg check /mnt/docker-aio-config/data/borg/borgbackup
|
|
exit
|
|
|
|
# Repair if needed (last resort)
|
|
docker exec nextcloud-aio-mastercontainer bash
|
|
export BORG_PASSPHRASE="0c038ada7a620e59802f43422b6fea409b46bab8821be6d3"
|
|
borg check --repair /mnt/docker-aio-config/data/borg/borgbackup
|
|
exit
|
|
```
|
|
|
|
### "Restore hangs or fails"
|
|
|
|
**Symptoms**: AIO restore doesn't complete
|
|
|
|
**Solutions**:
|
|
```bash
|
|
# Check available disk space
|
|
df -h /srv/NextCloud-AIO
|
|
|
|
# Check Docker resources
|
|
docker stats
|
|
|
|
# Check if daily_backup_running marker is stuck
|
|
docker exec nextcloud-aio-mastercontainer \
|
|
rm /mnt/docker-aio-config/data/daily_backup_running
|
|
|
|
# Restart and try again
|
|
docker restart nextcloud-aio-mastercontainer
|
|
```
|
|
|
|
### "Wrong Borg password"
|
|
|
|
**Symptoms**: Cannot restore or list backups
|
|
|
|
**Solution**:
|
|
- Verify password is exactly: `0c038ada7a620e59802f43422b6fea409b46bab8821be6d3`
|
|
- No spaces, no quotes when entering in AIO interface
|
|
- If password is truly lost, backups cannot be recovered
|
|
|
|
### "Kopia snapshot fails"
|
|
|
|
**Symptoms**: Tier 2 backup fails but AIO backup succeeds
|
|
|
|
**Solutions**:
|
|
```bash
|
|
# Check Kopia connection
|
|
kopia repository status
|
|
|
|
# Reconnect if needed
|
|
kopia repository disconnect
|
|
kopia repository connect server --url=...
|
|
|
|
# Check Kopia repository space
|
|
kopia repository status | grep Space
|
|
|
|
# Manually test snapshot
|
|
kopia snapshot create /opt/nextcloud-backups
|
|
```
|
|
|
|
### "Files missing after restore"
|
|
|
|
**Symptoms**: Nextcloud restored but files don't appear
|
|
|
|
**Solutions**:
|
|
```bash
|
|
# Rescan all files
|
|
docker exec -u www-data nextcloud-aio-nextcloud \
|
|
php occ files:scan --all
|
|
|
|
# Check file permissions
|
|
docker exec nextcloud-aio-nextcloud \
|
|
ls -la /mnt/ncdata/
|
|
|
|
# Verify datadir mount
|
|
docker inspect nextcloud-aio-nextcloud | grep -A 10 Mounts
|
|
|
|
# Check Nextcloud logs
|
|
docker exec nextcloud-aio-nextcloud \
|
|
tail -100 /var/www/html/data/nextcloud.log
|
|
```
|
|
|
|
## Advanced Topics
|
|
|
|
### Customizing Borg Retention Policy
|
|
|
|
Edit your docker-compose.yml:
|
|
|
|
```yaml
|
|
environment:
|
|
# Default: Keep 7 days, 4 weeks, 6 months
|
|
BORG_RETENTION_POLICY: --keep-within=7d --keep-weekly=4 --keep-monthly=6
|
|
|
|
# More aggressive (less space, shorter history)
|
|
# BORG_RETENTION_POLICY: --keep-within=3d --keep-weekly=2 --keep-monthly=3
|
|
|
|
# More conservative (more space, longer history)
|
|
# BORG_RETENTION_POLICY: --keep-within=14d --keep-weekly=8 --keep-monthly=24
|
|
```
|
|
|
|
Restart AIO:
|
|
```bash
|
|
cd /opt/nextcloud
|
|
docker compose down
|
|
docker compose up -d
|
|
```
|
|
|
|
### Backup to Multiple Kopia Repositories
|
|
|
|
For critical data, backup to multiple vaults:
|
|
|
|
```bash
|
|
# In backup script, after first Kopia snapshot:
|
|
|
|
# Connect to second repository
|
|
kopia repository disconnect
|
|
kopia repository connect server \
|
|
--url=https://backup2.example.com:51517 \
|
|
--override-username=admin \
|
|
--server-cert-fingerprint=...
|
|
|
|
# Create snapshots in second repository
|
|
kopia snapshot create /opt/nextcloud-backups
|
|
```
|
|
|
|
### Backup Notifications
|
|
|
|
Add to the end of `/opt/scripts/backup-nextcloud.sh`:
|
|
|
|
```bash
|
|
# Email notification
|
|
ADMIN_EMAIL="admin@example.com"
|
|
if [ $? -eq 0 ]; then
|
|
echo "Nextcloud backup completed successfully" | \
|
|
mail -s "✓ Nextcloud Backup Success" "$ADMIN_EMAIL"
|
|
else
|
|
echo "Nextcloud backup FAILED! Check /var/log/nextcloud-backup.log" | \
|
|
mail -s "✗ Nextcloud Backup FAILED" "$ADMIN_EMAIL"
|
|
fi
|
|
|
|
# Healthchecks.io ping
|
|
curl -fsS --retry 3 https://hc-ping.com/your-uuid-here
|
|
|
|
# Webhook notification
|
|
curl -X POST https://monitor.example.com/backup-status \
|
|
-H "Content-Type: application/json" \
|
|
-d '{"service":"nextcloud","status":"success"}'
|
|
```
|
|
|
|
### Excluding Directories from Backup
|
|
|
|
If certain directories don't need backup (temporary files, caches):
|
|
|
|
This must be configured through AIO's interface or environment variables. Check AIO documentation for current version's options for excluding paths.
|
|
|
|
### Manual Borg Operations
|
|
|
|
Advanced users can interact with Borg directly:
|
|
|
|
```bash
|
|
# Enter mastercontainer
|
|
docker exec -it nextcloud-aio-mastercontainer bash
|
|
|
|
# Set password
|
|
export BORG_PASSPHRASE="0c038ada7a620e59802f43422b6fea409b46bab8821be6d3"
|
|
|
|
# List all archives
|
|
borg list /mnt/docker-aio-config/data/borg/borgbackup
|
|
|
|
# Get info about specific archive
|
|
borg info /mnt/docker-aio-config/data/borg/borgbackup::<archive-name>
|
|
|
|
# Check repository
|
|
borg check /mnt/docker-aio-config/data/borg/borgbackup
|
|
|
|
# Compact repository (reclaim space)
|
|
borg compact /mnt/docker-aio-config/data/borg/borgbackup
|
|
|
|
# Exit
|
|
exit
|
|
```
|
|
|
|
## Additional Resources
|
|
|
|
- [Nextcloud AIO Official Documentation](https://github.com/nextcloud/all-in-one)
|
|
- [Nextcloud AIO Backup Documentation](https://github.com/nextcloud/all-in-one#backup-and-restore)
|
|
- [BorgBackup Documentation](https://borgbackup.readthedocs.io/)
|
|
- [Kopia Documentation](https://kopia.io/docs/)
|
|
- [Docker Volume Backup Best Practices](https://docs.docker.com/storage/volumes/#back-up-restore-or-migrate-data-volumes)
|
|
|
|
## Security Considerations
|
|
|
|
### BorgBackup Password
|
|
|
|
- **Never commit** the password to git repositories
|
|
- **Store securely** in password manager
|
|
- **Print and store** physical copy in safe
|
|
- **Share with team** via secure channel only
|
|
- **Document location** of password storage
|
|
|
|
### Kopia Repository Access
|
|
|
|
- Kopia repository credentials stored on server
|
|
- Limit access to backup server
|
|
- Use firewall rules to restrict Kopia server access
|
|
- Consider separate Kopia repositories for different services
|
|
|
|
### Network Security
|
|
|
|
- AIO admin interface (8080) - restrict access via firewall
|
|
- Apache interface (11000) - behind reverse proxy
|
|
- Kopia server (51516) - internal network only
|
|
|
|
## Revision History
|
|
|
|
| Date | Version | Changes |
|
|
|------|---------|---------|
|
|
| 2026-02-17 | 1.0 | Initial documentation - two-tier backup strategy using AIO's BorgBackup + Kopia |
|
|
|
|
---
|
|
|
|
**Last Updated**: February 17, 2026
|
|
**Maintained By**: System Administrator
|
|
**Review Schedule**: Quarterly
|
|
**Next Review**: May 17, 2026
|
|
|
|
**Critical Information**:
|
|
- BorgBackup Password: Store securely, required for all restores
|
|
- Backup Schedule: AIO 02:00, Kopia 03:00
|
|
- Kopia Server: 192.168.5.10:51516
|