Netgrimoire/nextcloud_backup.md
2026-02-18 04:40:24 +00:00

31 KiB

title description published date tags editor dateCreated
Nextcloud Backup Native + Kopia true 2026-02-18T04:40:14.455Z markdown 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

# 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

# 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

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:

    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:

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

# 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:

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:

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:

# 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:

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:

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

# 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

# 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

# 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

# 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

# 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:

#!/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:

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

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:

# 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

# 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

# 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

# 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

# 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

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

# 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

# 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

# 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:

# 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:

# 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:

# 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:

# 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:

# 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:

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:

cd /opt/nextcloud
docker compose down
docker compose up -d

Backup to Multiple Kopia Repositories

For critical data, backup to multiple vaults:

# 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:

# 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:

# 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

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