diff --git a/Infrastructure/Backups.md b/Infrastructure/Backups.md index c9005f4..abcc757 100644 --- a/Infrastructure/Backups.md +++ b/Infrastructure/Backups.md @@ -2,240 +2,877 @@ title: Setting Up Kopia description: published: true -date: 2026-01-27T16:19:56.250Z +date: 2026-02-11T19:43:03.807Z tags: editor: markdown dateCreated: 2026-01-23T22:14:17.009Z --- -## Configure Kopia on ZNAS -Installed docker on ZNAS -SERVER CERT SHA256: 696a4999f594b5273a174fd7cab677d8dd1628f9b9d27e557daa87103ee064b2 +# Kopia Backup System Documentation +## Overview -1. Used the gui to create the first repository at /srv/vault/kopia_repository -2. Entered the kopia container on znas `docker exec -it /bin/sh` -3. From the cli inside the container created the user for docker2 `kopia server users add --ask-password admin@docker2` +This system implements a two-tier backup strategy: +1. **Primary Repository** (`/srv/vault/kopia_repository`) - Full backups of all clients +2. **Vault Repository** (`/srv/vault/backup`) - Targeted critical data backups, replicated offsite via ZFS send/receive +The Vault repository sits on its own ZFS dataset to enable clean replication to offsite Pi systems. +--- -## Configure Kopia on first client +## Architecture -1. Use wget to get the kopia apt package and install on client -2. use dpkg to install on client -3. If this host has been configured before, remove old repository: - - `sudo kopia repository disconnect || true` - - `sudo rm -rf /root/.config/kopia` -4. Add new repository: `sudo kopia repo connect server --url=https://192.168.5.10:51515 --override-username=admin --server-cert-fingerprint=696a4999f594b5273a174fd7cab677d8dd1628f9b9d27e557daa87103ee064b2 -5. Create snapshot: `sudo kopia snapshot create /DockerVol/` -6. Add cronjob:` sudo crontab -e -added: -*/180 * * * * /usr/bin/kopia snapshot create /DockerVol >> /var/log/kopia-cron.log 2>&1` +``` +Clients (docker2, cindy's desktop, etc.) + ↓ + ├─→ Primary Backup → /srv/vault/kopia_repository (all data) + └─→ Vault Backup → /srv/vault/backup (critical data only) + ↓ + ZFS Send/Receive + ↓ + ┌───────┴───────┐ + ↓ ↓ + Pi Vault 1 Pi Vault 2 + (offsite) (offsite) +``` +--- +## Initial Setup on ZNAS -## Configure Kopia on Cindys desktop +### Prerequisites -1. wised winget to get the ui and cli version -2. Created user cindy@DESKTOP-QLSVD8P on repository server (password LucyDog123) -3. On windows - `kopia repo connect server --url=https://192.168.5.10:51515 --override-username=cindy --server-cert-fingerprint=696a4999f594b5273a174fd7cab677d8dd1628f9b9d27e557daa87103ee064b2` -4. Ran first snapshot: `kopia snapshot create C:\Users\cindy` -5. To save some space, modify the default policy `kopia policy set ` - --global ` - --add-ignore "**\AppData\Local\Temp\**" ` - --add-ignore "**\AppData\Local\Packages\**"` -Note: When createing tasks for cindy used password Harvey123= (ms password for ms account) -6. Create a backup script (recommended) - a. Create a folder: C:\scripts - b. Create the file: C:\Scripts\kopia-nightly.ps1 -` # Set repo password (simplest method) - $env:KOPIA_PASSWORD = "YOUR_REPOSITORY_PASSWORD" - # Run backup - kopia snapshot create C:\Users\cindy --progress` -7. Schedule this via Task Scheduler +- Docker installed on ZNAS +- ZFS pool available -Split policies (Documents vs everything else) +### 1. Create ZFS Datasets -Add backup failure notifications +```bash +# Primary repository dataset (if not already created) +zfs create -o mountpoint=/srv/vault zpool/vault +zfs create zpool/vault/kopia_repository -Tune performance for LAN speed +# Vault repository dataset (for offsite replication) +zfs create zpool/vault/backup +``` -Just say the word. +### 2. Install Kopia Server (Docker) -I would like to schedule a nightly backup +```bash +# Pull and run Kopia server container +docker run -d \ + --name kopia-server \ + --restart unless-stopped \ + -p 51515:51515 \ + -v /srv/vault/kopia_repository:/app/repository \ + -v /srv/vault/backup:/app/vault \ + -v /srv/vault/config:/app/config \ + -v /srv/vault/logs:/app/logs \ + kopia/kopia:latest server start \ + --address=0.0.0.0:51515 \ + --server-cert-fingerprint=696a4999f594b5273a174fd7cab677d8dd1628f9b9d27e557daa87103ee064b2 +``` + +**Note:** Server cert SHA256 fingerprint: `696a4999f594b5273a174fd7cab677d8dd1628f9b9d27e557daa87103ee064b2` + +### 3. Create Kopia Repositories + +```bash +# Enter the container +docker exec -it kopia-server /bin/sh + +# Create primary repository (if not already done via GUI) +# This was created via GUI at /srv/vault/kopia_repository + +# Create vault repository for offsite backups +kopia repository create filesystem --path=/app/vault + +# Exit container +exit +``` + +### 4. Create User Accounts + +```bash +# Enter container +docker exec -it kopia-server /bin/sh + +# Primary repository users +kopia server users add --ask-password admin@docker2 +kopia server users add --ask-password cindy@DESKTOP-QLSVD8P +# Password for cindy: LucyDog123 + +# Vault repository users (for targeted backups) +kopia repository connect filesystem --path=/app/vault +kopia server users add --ask-password admin@docker2-vault +kopia server users add --ask-password cindy@DESKTOP-QLSVD8P-vault +# Use same passwords or different based on security requirements + +# Exit container +exit +``` + +--- + +## Client Configuration + +### Linux Client (docker2) + +#### Primary Backup Setup + +1. **Install Kopia** + ```bash + # Download and install kopia .deb package + wget https://github.com/kopia/kopia/releases/download/v0.XX.X/kopia_0.XX.X_amd64.deb + sudo dpkg -i kopia_0.XX.X_amd64.deb + ``` + +2. **Remove old repository (if exists)** + ```bash + sudo kopia repository disconnect || true + sudo rm -rf /root/.config/kopia + ``` + +3. **Connect to primary repository** + ```bash + sudo kopia repository connect server \ + --url=https://192.168.5.10:51515 \ + --override-username=admin@docker2 \ + --server-cert-fingerprint=696a4999f594b5273a174fd7cab677d8dd1628f9b9d27e557daa87103ee064b2 + ``` + +4. **Create initial snapshot** + ```bash + sudo kopia snapshot create /DockerVol/ + ``` + +5. **Set up cron job for primary backups** + ```bash + sudo crontab -e + + # Add this line (runs every 3 hours) + */180 * * * * /usr/bin/kopia snapshot create /DockerVol >> /var/log/kopia-primary-cron.log 2>&1 + ``` + +#### Vault Backup Setup (Critical Data) + +1. **Create secondary kopia config directory** + ```bash + sudo mkdir -p /root/.config/kopia-vault + ``` + +2. **Connect to vault repository** + ```bash + sudo kopia --config-file=/root/.config/kopia-vault/repository.config \ + repository connect server \ + --url=https://192.168.5.10:51515 \ + --override-username=admin@docker2-vault \ + --server-cert-fingerprint=696a4999f594b5273a174fd7cab677d8dd1628f9b9d27e557daa87103ee064b2 + ``` + +3. **Create vault backup script** + ```bash + sudo nano /usr/local/bin/kopia-vault-backup.sh + ``` + + Add this content: + ```bash + #!/bin/bash + # Kopia Vault Backup Script + # Backs up critical data to vault repository for offsite replication + + KOPIA_CONFIG="/root/.config/kopia-vault/repository.config" + LOG_FILE="/var/log/kopia-vault-cron.log" + + # Add your critical directories here + VAULT_DIRS=( + "/DockerVol/critical-app1" + "/DockerVol/critical-app2" + "/home/admin/documents" + ) + + echo "=== Vault backup started at $(date) ===" >> "$LOG_FILE" + + for dir in "${VAULT_DIRS[@]}"; do + if [ -d "$dir" ]; then + echo "Backing up: $dir" >> "$LOG_FILE" + /usr/bin/kopia --config-file="$KOPIA_CONFIG" snapshot create "$dir" >> "$LOG_FILE" 2>&1 + else + echo "Directory not found: $dir" >> "$LOG_FILE" + fi + done + + echo "=== Vault backup completed at $(date) ===" >> "$LOG_FILE" + echo "" >> "$LOG_FILE" + ``` + +4. **Make script executable** + ```bash + sudo chmod +x /usr/local/bin/kopia-vault-backup.sh + ``` + +5. **Set up cron job for vault backups** + ```bash + sudo crontab -e + + # Add this line (runs daily at 3 AM) + 0 3 * * * /usr/local/bin/kopia-vault-backup.sh + ``` + +--- + +### Windows Client (Cindy's Desktop) + +#### Primary Backup Setup + +1. **Install Kopia** + ```powershell + # Using winget + winget install kopia + ``` + +2. **Connect to primary repository** + ```powershell + kopia repository connect server ` + --url=https://192.168.5.10:51515 ` + --override-username=cindy@DESKTOP-QLSVD8P ` + --server-cert-fingerprint=696a4999f594b5273a174fd7cab677d8dd1628f9b9d27e557daa87103ee064b2 + ``` + +3. **Create initial snapshot** + ```powershell + kopia snapshot create C:\Users\cindy + ``` + +4. **Set exclusion policy** + ```powershell + kopia policy set ` + --global ` + --add-ignore "**\AppData\Local\Temp\**" ` + --add-ignore "**\AppData\Local\Packages\**" + ``` + +5. **Create primary backup script** + ```powershell + # Create scripts folder + New-Item -ItemType Directory -Force -Path C:\Scripts + + # Create backup script + New-Item -ItemType File -Path C:\Scripts\kopia-primary-nightly.ps1 + ``` + + Add this content to `C:\Scripts\kopia-primary-nightly.ps1`: + ```powershell + # Kopia Primary Backup Script + # Repository password + $env:KOPIA_PASSWORD = "LucyDog123" + + # Run backup with logging + kopia snapshot create C:\Users\cindy ` + --progress ` + | Tee-Object -FilePath C:\Logs\kopia-primary.log -Append + + # Log completion + Add-Content -Path C:\Logs\kopia-primary.log -Value "Backup completed at $(Get-Date)" + Add-Content -Path C:\Logs\kopia-primary.log -Value "---" + ``` + +6. **Secure the script** + - Right-click `C:\Scripts\kopia-primary-nightly.ps1` → Properties → Security + - Ensure only Cindy's user account has read access + +7. **Create scheduled task for primary backup** + - Press `Win + R` → type `taskschd.msc` + - Click "Create Task" (not "Basic Task") + + **General tab:** + - Name: `Kopia Primary Nightly Backup` + - ✔ Run whether user is logged on or not + - ✔ Run with highest privileges + - Configure for: Windows 10/11 + + **Triggers tab:** + - New → Daily at 2:00 AM + - ✔ Enabled + + **Actions tab:** + - Program: `powershell.exe` + - Arguments: `-ExecutionPolicy Bypass -File C:\Scripts\kopia-primary-nightly.ps1` + - Start in: `C:\Scripts` + + **Conditions tab:** + - ✔ Wake the computer to run this task + - ✔ Start only if on AC power (recommended for laptops) + + **Settings tab:** + - ✔ Allow task to be run on demand + - ✔ Run task as soon as possible after scheduled start is missed + - ❌ Stop the task if it runs longer than... + + **Note:** When creating the task, use PIN (not Windows password) when prompted. For scheduled task credential: use password Harvey123= (MS account password) + +#### Vault Backup Setup (Critical Data) + +1. **Create vault config directory** + ```powershell + New-Item -ItemType Directory -Force -Path C:\Users\cindy\.config\kopia-vault + ``` + +2. **Connect to vault repository** + ```powershell + kopia --config-file="C:\Users\cindy\.config\kopia-vault\repository.config" ` + repository connect server ` + --url=https://192.168.5.10:51515 ` + --override-username=cindy@DESKTOP-QLSVD8P-vault ` + --server-cert-fingerprint=696a4999f594b5273a174fd7cab677d8dd1628f9b9d27e557daa87103ee064b2 + ``` + +3. **Create vault backup script** + ```powershell + New-Item -ItemType File -Path C:\Scripts\kopia-vault-nightly.ps1 + ``` + + Add this content to `C:\Scripts\kopia-vault-nightly.ps1`: + ```powershell + # Kopia Vault Backup Script + # Backs up critical data to vault repository for offsite replication + + $env:KOPIA_PASSWORD = "LucyDog123" + $KOPIA_CONFIG = "C:\Users\cindy\.config\kopia-vault\repository.config" + + # Define critical directories to back up + $VaultDirs = @( + "C:\Users\cindy\Documents", + "C:\Users\cindy\Pictures", + "C:\Users\cindy\Desktop\Important" + ) + + # Log header + Add-Content -Path C:\Logs\kopia-vault.log -Value "=== Vault backup started at $(Get-Date) ===" + + # Backup each directory + foreach ($dir in $VaultDirs) { + if (Test-Path $dir) { + Add-Content -Path C:\Logs\kopia-vault.log -Value "Backing up: $dir" + kopia --config-file="$KOPIA_CONFIG" snapshot create $dir ` + | Tee-Object -FilePath C:\Logs\kopia-vault.log -Append + } else { + Add-Content -Path C:\Logs\kopia-vault.log -Value "Directory not found: $dir" + } + } + + # Log completion + Add-Content -Path C:\Logs\kopia-vault.log -Value "=== Vault backup completed at $(Get-Date) ===" + Add-Content -Path C:\Logs\kopia-vault.log -Value "" + ``` + +4. **Create log directory** + ```powershell + New-Item -ItemType Directory -Force -Path C:\Logs + ``` + +5. **Create scheduled task for vault backup** + - Press `Win + R` → type `taskschd.msc` + - Click "Create Task" + + **General tab:** + - Name: `Kopia Vault Nightly Backup` + - ✔ Run whether user is logged on or not + - ✔ Run with highest privileges + + **Triggers tab:** + - New → Daily at 3:00 AM (after primary backup) + - ✔ Enabled + + **Actions tab:** + - Program: `powershell.exe` + - Arguments: `-ExecutionPolicy Bypass -File C:\Scripts\kopia-vault-nightly.ps1` + - Start in: `C:\Scripts` + + **Conditions/Settings:** Same as primary backup task + +--- + +## ZFS Replication to Offsite Pi Vaults + +### Setup on ZNAS (Source) + +1. **Create snapshot script** + ```bash + sudo nano /usr/local/bin/vault-snapshot.sh + ``` + + Add this content: + ```bash + #!/bin/bash + # Create ZFS snapshot of vault dataset for replication + + DATASET="zpool/vault/backup" + SNAPSHOT_NAME="vault-$(date +%Y%m%d-%H%M%S)" + + # Create snapshot + zfs snapshot "${DATASET}@${SNAPSHOT_NAME}" + + # Keep only last 7 days of snapshots on source + zfs list -t snapshot -o name -s creation | grep "^${DATASET}@vault-" | head -n -7 | xargs -r -n 1 zfs destroy + + echo "Created snapshot: ${DATASET}@${SNAPSHOT_NAME}" + ``` + +2. **Make executable** + ```bash + sudo chmod +x /usr/local/bin/vault-snapshot.sh + ``` + +3. **Schedule snapshot creation** + ```bash + sudo crontab -e + + # Add this line (create snapshot daily at 4 AM, after vault backups complete) + 0 4 * * * /usr/local/bin/vault-snapshot.sh >> /var/log/vault-snapshot.log 2>&1 + ``` + +4. **Create replication script** + ```bash + sudo nano /usr/local/bin/vault-replicate.sh + ``` + + Add this content: + ```bash + #!/bin/bash + # Replicate vault dataset to offsite Pi systems + + DATASET="zpool/vault/backup" + PI1_HOST="pi-vault-1.local" # Update with actual hostname/IP + PI2_HOST="pi-vault-2.local" # Update with actual hostname/IP + PI_USER="admin" + REMOTE_DATASET="tank/vault-backup" # Update with actual dataset on Pi + + # Get the latest snapshot + LATEST_SNAP=$(zfs list -t snapshot -o name -s creation | grep "^${DATASET}@vault-" | tail -n 1) + + if [ -z "$LATEST_SNAP" ]; then + echo "No snapshots found for replication" + exit 1 + fi + + echo "Replicating snapshot: $LATEST_SNAP" + + # Function to replicate to a target + replicate_to_target() { + local TARGET_HOST=$1 + echo "=== Replicating to $TARGET_HOST ===" + + # Get the last snapshot on remote (if any) + LAST_REMOTE=$(ssh ${PI_USER}@${TARGET_HOST} "zfs list -t snapshot -o name -s creation 2>/dev/null | grep '^${REMOTE_DATASET}@vault-' | tail -n 1" || echo "") + + if [ -z "$LAST_REMOTE" ]; then + # Initial replication (full send) + echo "Performing initial full replication to $TARGET_HOST" + zfs send -c $LATEST_SNAP | ssh ${PI_USER}@${TARGET_HOST} "zfs receive -F ${REMOTE_DATASET}" + else + # Incremental replication + echo "Performing incremental replication to $TARGET_HOST" + LAST_SNAP_NAME=$(echo $LAST_REMOTE | cut -d'@' -f2) + zfs send -c -i ${DATASET}@${LAST_SNAP_NAME} $LATEST_SNAP | ssh ${PI_USER}@${TARGET_HOST} "zfs receive -F ${REMOTE_DATASET}" + fi + + # Clean up old snapshots on remote (keep last 30 days) + ssh ${PI_USER}@${TARGET_HOST} "zfs list -t snapshot -o name -s creation | grep '^${REMOTE_DATASET}@vault-' | head -n -30 | xargs -r -n 1 zfs destroy" + + echo "Replication to $TARGET_HOST completed" + } + + # Replicate to both Pi systems + replicate_to_target $PI1_HOST + replicate_to_target $PI2_HOST + + echo "All replications completed at $(date)" + ``` + +5. **Make executable** + ```bash + sudo chmod +x /usr/local/bin/vault-replicate.sh + ``` + +6. **Set up SSH keys for passwordless replication** + ```bash + # Generate SSH key if needed + ssh-keygen -t ed25519 -C "znas-replication" + + # Copy to both Pi systems + ssh-copy-id admin@pi-vault-1.local + ssh-copy-id admin@pi-vault-2.local + ``` + +7. **Schedule replication** + ```bash + sudo crontab -e + + # Add this line (replicate daily at 5 AM, after snapshot creation) + 0 5 * * * /usr/local/bin/vault-replicate.sh >> /var/log/vault-replicate.log 2>&1 + ``` + +### Setup on Pi Vault Systems (Targets) + +Repeat these steps on both Pi Vault 1 and Pi Vault 2: + +1. **Create ZFS pool on SSD** (if not already done) + ```bash + # Assuming SSD is /dev/sda + sudo zpool create tank /dev/sda + ``` + +2. **Create dataset for receiving backups** + ```bash + sudo zfs create tank/vault-backup + ``` + +3. **Set appropriate permissions** + ```bash + # Allow the replication user to receive snapshots + sudo zfs allow admin receive,create,mount,destroy tank/vault-backup + ``` + +4. **Verify replication** (after first run) + ```bash + zfs list -t snapshot | grep vault- + ``` + +--- + +## Maintenance and Monitoring + +### Regular Health Checks + +**On Clients:** +```bash +# Linux +sudo kopia snapshot list +sudo kopia snapshot verify --file-parallelism=8 +sudo kopia repository status + +# Windows (PowerShell) +kopia snapshot list +kopia snapshot verify --file-parallelism=8 +kopia repository status +``` + +**On ZNAS:** +```bash +# Check ZFS health +zpool status + +# Check vault snapshots +zfs list -t snapshot | grep "vault/backup" + +# Check replication logs +tail -f /var/log/vault-replicate.log +``` + +**On Pi Vaults:** +```bash +# Check received snapshots +zfs list -t snapshot | grep vault-backup + +# Check available space +zfs list tank/vault-backup +``` + +### Monthly Maintenance Tasks + +1. **Verify vault backups are replicating** + ```bash + # On ZNAS + cat /var/log/vault-replicate.log | grep "completed" + + # On Pi systems + zfs list -t snapshot -o name,creation | grep vault-backup | tail + ``` + +2. **Test restore from vault repository** + ```bash + # Connect to vault repo and verify a random snapshot + kopia --config-file=/path/to/vault/config repository connect server --url=... + kopia snapshot list + kopia snapshot verify --file-parallelism=8 + ``` -Perfect — let’s wire this up so it just runs every night and you never think about it again 😄 -This is the clean, reliable way to schedule Kopia CLI on Windows. +3. **Check disk space on all systems** -I’ll assume: +4. **Review backup logs for errors** -Repo is already connected +### Backup Policy Recommendations -You want to back up C:\Users\cindy +**Primary Repository:** +- Retention: 7 daily, 4 weekly, 6 monthly +- Compression: enabled +- All data from clients -You’re okay using Windows Task Scheduler (best option) +**Vault Repository:** +- Retention: 14 daily, 8 weekly, 12 monthly, 3 yearly +- Compression: enabled +- Only critical data for offsite protection -1️⃣ Create a backup script (recommended) +**ZFS Snapshots:** +- Keep 7 days on ZNAS (source) +- Keep 30 days on Pi vaults (targets) -Create a folder: +--- -C:\Scripts +## Disaster Recovery Procedures +### Scenario 1: Restore from Primary Repository -Create this file: +```bash +# Linux +sudo kopia snapshot list +sudo kopia snapshot restore /restore/location -C:\Scripts\kopia-nightly.ps1 +# Windows +kopia snapshot list +kopia snapshot restore C:\restore\location +``` +### Scenario 2: Restore from Vault Repository (Offsite) -Put this in it: +If ZNAS is unavailable, restore directly from Pi vault: -# Set repo password (simplest method) -$env:KOPIA_PASSWORD = "YOUR_REPOSITORY_PASSWORD" +1. **On Pi vault:** + ```bash + # Mount the latest snapshot + LATEST=$(zfs list -t snapshot -o name | grep vault-backup | tail -n 1) + zfs clone $LATEST tank/vault-backup-restore + ``` -# Run backup -kopia snapshot create C:\Users\cindy --progress +2. **Access Kopia repository directly:** + ```bash + kopia repository connect filesystem --path=/tank/vault-backup-restore + kopia snapshot list + kopia snapshot restore /restore/location + ``` -🔐 Secure the script +3. **Clean up after restore:** + ```bash + zfs destroy tank/vault-backup-restore + ``` -Right-click → Properties → Security +### Scenario 3: Complete System Rebuild -Ensure only your user has read access +1. Rebuild ZNAS and restore vault dataset from Pi +2. Reinstall Kopia server in Docker +3. Point server to restored vault repository +4. Reconnect clients to primary and vault repositories +5. Resume scheduled backups -This prevents password exposure +--- -If you want a more secure option later, we can move the password to Windows Credential Manager. +## Troubleshooting -2️⃣ Create the scheduled task +### Client can't connect to repository -Press Win + R → type: +```bash +# Check server is running +docker ps | grep kopia -taskschd.msc +# Check firewall +sudo ufw status | grep 51515 -Create Task (not “Basic Task”) +# Verify certificate fingerprint +# SERVER CERT SHA256: 696a4999f594b5273a174fd7cab677d8dd1628f9b9d27e557daa87103ee064b2 +``` -General tab +### Vault replication failing -Name: Kopia Nightly Backup +```bash +# Check SSH connectivity +ssh admin@pi-vault-1.local "echo Connected" -✔ Run whether user is logged on or not +# Check ZFS pool health +zpool status -✔ Run with highest privileges +# Check remote dataset exists +ssh admin@pi-vault-1.local "zfs list tank/vault-backup" -Configure for: your Windows version +# Manual test send +zfs send -n -v zpool/vault/backup@latest | ssh admin@pi-vault-1.local "cat > /dev/null" +``` -Triggers tab +### Windows scheduled task not running -New… +- Check Task Scheduler → Task History +- Verify PIN/password authentication (use password Harvey123= for task credential) +- Check that computer is awake at scheduled time +- Review power settings (prevent sleep, wake for tasks) +- Check log files: `C:\Logs\kopia-primary.log` and `C:\Logs\kopia-vault.log` -Begin task: On a schedule +### Snapshot cleanup not working -Daily +```bash +# Manually clean old snapshots +zfs list -t snapshot -o name,used,creation | grep vault-backup -Time: 2:00 AM (or whenever you like) +# Remove specific snapshot +zfs destroy zpool/vault/backup@vault-YYYYMMDD-HHMMSS +``` -✔ Enabled +--- -Actions tab +## Security Notes -New… +1. **Passwords in scripts:** Current implementation stores passwords in plaintext in scripts. For production, consider: + - Windows Credential Manager + - Linux keyring or encrypted credential storage + - Environment variables set at system level -Action: Start a program +2. **SSH keys:** Replication uses SSH keys. Keep private keys secure and use passphrase protection where possible. -Program/script: +3. **Network security:** Kopia server uses HTTPS with certificate validation. Ensure certificate fingerprint is verified on first connection. -powershell.exe +4. **Physical security:** Offsite Pi vaults should be stored in secure locations with different risk profiles (fire, flood, theft). +--- -Add arguments: +## Quick Reference Commands --ExecutionPolicy Bypass -File C:\Scripts\kopia-nightly.ps1 - - -Start in: - -C:\Scripts - -Conditions tab (important) - -Recommended settings: - -✔ Wake the computer to run this task - -❌ Stop if the computer switches to battery (your choice) - -❌ Start only if on AC power (recommended for laptops) - -Settings tab - -✔ Allow task to be run on demand - -✔ Run task as soon as possible after a scheduled start is missed - -❌ Stop the task if it runs longer than… (don’t limit it) - -3️⃣ Test the task immediately - -Right-click the task → Run - -Then check: +### Kopia Client Commands +```bash +# List snapshots kopia snapshot list +# Create snapshot +kopia snapshot create /path/to/backup -You should see a fresh snapshot. +# Verify integrity +kopia snapshot verify --file-parallelism=8 -4️⃣ (Strongly recommended) Add logging - -Update your script to this: - -$env:KOPIA_PASSWORD = "YOUR_REPOSITORY_PASSWORD" - -kopia snapshot create C:\Users\cindy ` - --progress ` - | Tee-Object -FilePath C:\Logs\kopia.log -Append - - -Create the log folder once: - -mkdir C:\Logs - - -Now you have a paper trail if anything ever fails. - -5️⃣ Common laptop gotchas (especially Dell Latitudes) - -Make sure: - -Sleep is disabled or delayed overnight - -Lid close action = Do nothing - -Network adapter power saving = ❌ disabled - -Otherwise the task runs, but the network drops mid-backup. - -Quick health checks (monthly) -kopia snapshot list -kopia snapshot verify +# Check repository status kopia repository status -Optional next upgrades +# View policies +kopia policy list -If you want, I can help you: +# Mount snapshot (Linux) +kopia mount /mnt/snapshot -🔐 Store the password securely (no plaintext) +# Use alternate config (for vault repository) +kopia --config-file=/path/to/vault/repository.config snapshot list +``` -📧 Email yourself on backup failure +### ZFS Commands -🗂️ Add multiple sources with different policies +```bash +# List snapshots +zfs list -t snapshot -🧹 Schedule weekly maintenance automatically +# Create manual snapshot +zfs snapshot zpool/vault/backup@manual-$(date +%Y%m%d) -🐧 Verify snapshots from the Linux server +# Send full snapshot +zfs send zpool/vault/backup@snapshot | ssh user@host zfs receive tank/backup -Just tell me how “hands-off” you want this to be — you’re already 90% of the way to a pro-grade backup setup 💪 +# Send incremental +zfs send -i @old @new zpool/vault/backup | ssh user@host zfs receive tank/backup -user does not know her windows password, only her pin +# List replication progress +zpool status -v -Ah — that’s an important detail 👍 +# Check dataset size +zfs list -o space zpool/vault/backup +``` + +--- + +## Appendix: System Specifications + +**ZNAS:** +- ZFS fileserver +- Docker running Kopia server +- IP: 192.168.5.10 +- Datasets: + - `/srv/vault/kopia_repository` (zpool/vault/kopia_repository) - Primary repository + - `/srv/vault/backup` (zpool/vault/backup) - Vault repository (replicated) + +**Clients:** +- **docker2** (Linux) - Backs up /DockerVol/ + - Primary: Every 3 hours + - Vault: Daily at 3 AM (critical directories only) +- **DESKTOP-QLSVD8P** (Windows - Cindy's desktop) - Backs up C:\Users\cindy + - Primary: Daily at 2 AM + - Vault: Daily at 3 AM (Documents, Pictures, Important files) + - Kopia password: LucyDog123 + - Task Scheduler credential: Harvey123= + +**Offsite Vaults:** +- **Pi Vault 1** - Raspberry Pi with SSD (tank/vault-backup) +- **Pi Vault 2** - Raspberry Pi with SSD (tank/vault-backup) + +**Server Certificate:** +- SHA256: `696a4999f594b5273a174fd7cab677d8dd1628f9b9d27e557daa87103ee064b2` + +--- + +## Workflow Summary + +### Daily Backup Flow + +**2:00 AM** - Cindy's desktop primary backup runs +**3:00 AM** - docker2 vault backup runs +**3:00 AM** - Cindy's desktop vault backup runs +**4:00 AM** - ZNAS creates ZFS snapshot of vault dataset +**5:00 AM** - ZNAS replicates vault snapshot to both Pi systems +**Every 3 hours** - docker2 primary backup runs + +### What Gets Backed Up Where + +**Primary Repository (Full Backups):** +- docker2: /DockerVol/ (all Docker volumes) +- Cindy: C:\Users\cindy (entire user profile, minus temp files) + +**Vault Repository (Critical Data for Offsite):** +- docker2: Selected critical Docker volumes +- Cindy: Documents, Pictures, Important desktop files + +**Offsite (Via ZFS Send):** +- Entire vault repository (all clients' critical data) +- Replicated to 2 separate Pi systems + +--- + +## Future Enhancements + +Consider adding: +- Email notifications on backup failures +- Monitoring dashboard (Grafana/Prometheus) +- Backup validation automation +- Additional retention policies per client +- Encrypted credentials storage +- Remote monitoring of Pi vault systems +- Automated restore testing +- Bandwidth throttling for replication +- Multiple ZFS snapshot retention policies + +--- + +## Change Log + +- **2025-02-11** - Initial comprehensive documentation created + - Added two-tier backup strategy (primary + vault) + - Added ZFS replication procedures for offsite backup + - Added Pi vault setup instructions + - Added disaster recovery procedures + - Consolidated all client configurations + - Added workflow diagrams and timing + +--- + +## Support and Feedback + +For issues or improvements to this documentation, contact the system administrator. + +**Useful Resources:** +- Kopia Documentation: https://kopia.io/docs/ +- ZFS Administration Guide: https://openzfs.github.io/openzfs-docs/ +- Kopia GitHub: https://github.com/kopia/kopia