Offsite-Backups mit UniFi NAS Kopia Backup Software (Docker) Portunity secureBackup (S3)

Aus Portunity Wiki

Wechseln zu: Navigation, Suche

Inhaltsverzeichnis

Zielbild (kurz)

Dieses Setup kombiniert zwei Dinge:

  • Schnelle lokale Wiederherstellung über Snapshots auf dem UniFi NAS (für „Mist gebaut / Datei versehentlich gelöscht“).
  • Echte externe Datensicherung (Offsite) über Kopia-Snapshots in ein Portunity Secure-Backup S3-Bucket – inkrementell, dedupliziert, mit Aufbewahrungsregeln (täglich/wöchentlich/monatlich), ohne 20-fache Vollkopien.

UniFi Drive/Unifi UNAS Pro 8 & Co bietet aktuell primär Backup als 1:1-Kopie (Delta bezogen auf Dateien). Für längere Historien und „richtige“ Snapshot-Backups mit Dedupe/Encryption setzen wir deshalb Kopia auf einem separaten Docker-Host ein.

Hinweis:

  • Wir haben das im Mitarbeiter-Kreis mit einem Unifi NAS Pro 8 getestet und dies von daher hier auch benannt. Die Anleitung ist aber allgemeingültig auch für andere NAS-Systeme wie Synology, QNAP, Windows-Freigabe, Linux Samba-Dienste u.a. und sollte dort ähnlich / gleichwertig funktionieren und stellt keine Wertung oder Empfehlung für Unifi von Ubiquiti dar.
  • Auf NAS-Systemen anderer Hersteller haben Sie aber möglicherweise auch gesonderte / herstellereigene Backup-Lösungen, welche über eine 1:1 Kopie analog zu Kopia auch inkrementelle und deduplizierte Backups direkt vom NAS aus ermöglichen. Dennoch kann auch dabei Kopia Sinn machen, wenn Sie weitere Backupquellen einbinden möchten.

Architektur

Komponenten:

  • UniFi NAS Pro 8 mit mehreren SMB-Shares (z. B. Daten, Homeassistant, Paperless, Kasse, Media).
    • oder andere NAS-Systeme wie Synology, QNAP, FreeNas, Windows-Freigaben u.a.
  • Docker-Host (Linux) im gleichen Netz:
    • mountet SMB-Shares read-only (quellseitig)
    • stellt ein separates SMB-Share „Restore“ read-write bereit (zielseitig)
    • betreibt Kopia als Docker-Container (Web-UI + Scheduler).
  • Portunity Secure-Backup (S3 kompatibel) als Offsite-Ziel (Ceph Object Storage).
  • HomeAssistant, lokales PaperLess & weitere Systeme
    • sichern lokal zunächst 1x als 1:1 Kopie auf dem NAS, z.B. Paperless-Exporter via Cronjob, via Cronjob über Rsync o.ä.
    • bzw. legen ihre von Haus aus möglichen Sicherungen auf einem Share ab, z.B. HomeAssistant, Registrierkassen o.ä. haben ein integriertes Backup, z.B. täglich für X Tage o.üä.

Warum read-only Mounts? Der Backup-Host soll im Normalbetrieb keine Produktivdaten verändern können. Restore erfolgt bewusst über ein separates Restore-Ziel.

UniFi NAS: Shares & lokale Snapshots

Auf dem UniFi NAS werden die Shares wie gewohnt angelegt. Lokale Snapshots sind optional, aber sehr praktisch.

Wichtiger Hinweis zur UniFi-Snapshot-Logik: Pro Share ist in der UI typischerweise nur ein Snapshot-Schedule möglich (z. B. täglich ODER wöchentlich). Deshalb empfehlen wir:

  • Produktiv-Shares (z. B. Daten, Paperless): täglich (z. B. 30–90 Versionen)
  • Reine Backup-Shares (z. B. Backup_Paperless, Backup_Homeassistant): wöchentlich (z. B. 8–12)
  • Große, „nice-to-have“ Daten (z. B. Media/Filmarchive): optional keine lokalen Snapshots

Das ersetzt keine Offsite-Sicherung, ist aber für schnelle Rollbacks ideal. Bitte verwechsels Sie die Snapshoots auf dem NAS nicht mit den Snapshoots innerhalb von Kopia - dies sind zwei völlig getrennte Welten!

Portunity secureBackup (S3): Zugangsdaten finden

Im Portunity Webinterface finden Sie pro Vertrag/Produkt eine „S3-kompatible Schnittstelle“ mit der Möglichkeit einen oder mehrere Buckets anzulegen.

Screenshot (Beispiel):

Datei:Secure-backup-s3-schnittstelle.jpg
Portunity Secure-Backup – S3-Schnittstelle (Beispielansicht).

Welche Felder braucht Kopia?

  • S3-Bucket → Kopia Parameter: --bucket
  • Key-ID → Environment: AWS_ACCESS_KEY_ID / S3_ACCESS_KEY
  • Secret Access Key → Environment: AWS_SECRET_ACCESS_KEY / S3_SECRET_KEY
  • S3-Region → Kopia Parameter: --region
  • S3-Pfad / Endpoint → Kopia Parameter: --endpoint

Wichtig (Stolperfalle): Bei Kopia muss --endpoint nur der Hostname sein (ohne https:// und ohne /bucket-Pfad via bei Portunity ausgegeben mit s3://avcd123456.s3.backup1.portunityhosted.de/backup00000001-01). Beispiel:

  • korrekt: --endpoint=avcd123456.s3.backup1.portunityhosted.de
  • falsch: --endpoint=s3://avcd123456.s3.backup1.portunityhosted.de/backup00000001-01

Docker-Host: SMB-Mounts vorbereiten

Wir mounten die UniFi-Shares auf dem Docker-Host unter /mnt. Quellen sind read-only, Restore ist read-write.

Beispiel-Verzeichnislayout

/mnt/backup-daten          (ro)  -> UniFi Share "Daten"
/mnt/backup-homeassistant  (ro)  -> UniFi Share "Backup_Homeassistant"
/mnt/backup-kasse          (ro)  -> UniFi Share "Backup_Kasse"
/mnt/paperless-backup      (ro)  -> UniFi Share "Backup_Paperless"
/mnt/backup-restore        (rw)  -> UniFi Share "Backup_Restore" (oder ähnlicher Name)

Mount per /etc/fstab (Beispiel)

# Credentials-Dateien sollten root-only sein (chmod 600)
# Beispiel: /etc/samba/cred_backup-daten
 
//192.168.220.3/Daten              /mnt/backup-daten          cifs  credentials=/etc/samba/cred_backup-daten,vers=3.0,iocharset=utf8,ro,nofail,x-systemd.automount,uid=1000,gid=1000,dir_mode=0555,file_mode=0444  0  0
//192.168.220.3/Backup_Homeassistant /mnt/backup-homeassistant cifs  credentials=/etc/samba/cred_backup-ha,vers=3.0,iocharset=utf8,ro,nofail,x-systemd.automount,uid=1000,gid=1000,dir_mode=0555,file_mode=0444  0  0
//192.168.220.3/Backup_Kasse        /mnt/backup-kasse         cifs  credentials=/etc/samba/cred_backup-kasse,vers=3.0,iocharset=utf8,ro,nofail,x-systemd.automount,uid=1000,gid=1000,dir_mode=0555,file_mode=0444  0  0
//192.168.220.3/Backup_Paperless    /mnt/backup-paperless     cifs  credentials=/etc/samba/cred_backup-paperless,vers=3.0,iocharset=utf8,ro,nofail,x-systemd.automount,uid=1000,gid=1000,dir_mode=0555,file_mode=0444  0  0
 
//192.168.220.3/Backup_Restore      /mnt/backup-restore       cifs  credentials=/etc/samba/cred_backup-restore,vers=3.0,iocharset=utf8,rw,nofail,x-systemd.automount,uid=1000,gid=1000,dir_mode=0770,file_mode=0660  0  0

Hinweis: uid und gid sollten auf einen angelegten User und Gruppe von der ID passend sein, so dass Kopia an die Daten auch dran kommt. Am besten der selbe User, unter dem von Kopia auch der Doccer dann läuft.

Credentials-Datei (Beispiel):

username=BACKUPUSER
password=SUPERGEHEIM
domain=WORKGROUP

Kopia in Docker installieren

Wir betreiben Kopia als Container mit:

  • persistenter Config/Cache/Logs auf dem Host
  • read-only Sources (SMB-Mounts)
  • separatem Restore-Ziel (rw)
  • Web-UI via Reverse Proxy (empfohlen: TLS)

Ordnerstruktur

/home/kopia/kopia/
  docker-compose.yml
  .env
  config/
  cache/
  logs/
/mnt/
  backup-daten/
  backup-homeassistant/
  backup-kasse/
  backup-paperless/     
  backup-restore/

.env (Beispiel, anonymisiert)

# Repository-Passwort (verschlüsselt ALLES im Repo; unbedingt sicher verwahren!)
KOPIA_PASSWORD=RANDOM-LONG-PASSPHRASE
 
# Web-UI Login für Kopia-Server (nur UI/API Zugriff, NICHT die Repo-Verschlüsselung)
KOPIA_UI_USER=admnin
KOPIA_UI_PASS=RANDOM-UI-PASSWORD
 
# Portunity Secure-Backup (S3/Ceph)
S3_ACCESS_KEY=AKIAxxxxxxxxxxxxxxxx
S3_SECRET_KEY=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

Warum drei Passwörter?

  • KOPIA_PASSWORD ist das Repository-Passwort (Key-Derivation/Encryption) – ohne dieses Passwort ist das Backup praktisch unlesbar. Mit diesem Passwort werden die Daten bei Portunity im secureBackup Speicher (=Repository) verschlüsselt. Bitte speichern Sie sich das Passwort sicher in Ihrem Passwort-Tresor oder Offline irgendwo sicher. Sollte der Docker-Host lokal ausfallen kommen Sie ohne dieses Passwort nicht mehr an Ihre gesicherten Daten lesbar heran.
  • KOPIA_UI_USER/KOPIA_UI_PASS ist der Login für den Kopia-Server für das lokale Web-UI und die API. Das schützt den Zugriff auf die Bedienoberfläche, ändert aber nicht die Verschlüsselung im Repository bei Portunity.
  • S3_ACCESS_KEY / S3_SECRET_KEY sind die Zugangsdaten zum angelegten s3-Bucket vom Portunity secureBackup.

docker-compose.yml (Beispiel)

services:
  kopia:
    image: kopia/kopia:latest
    container_name: kopia
    restart: unless-stopped
    ports:
      - "51515:51515"
    environment:
      TZ: Europe/Berlin
 
      # WICHTIG: Config-Pfad zeigt auf eine Datei, nicht auf ein Verzeichnis
      KOPIA_CONFIG_PATH: /app/config/kopia.config
      KOPIA_CACHE_DIRECTORY: /app/cache
      KOPIA_LOG_DIR: /app/logs
 
      KOPIA_PASSWORD: "${KOPIA_PASSWORD}"
      AWS_ACCESS_KEY_ID: "${S3_ACCESS_KEY}"
      AWS_SECRET_ACCESS_KEY: "${S3_SECRET_KEY}"
 
    volumes:
      - ./config:/app/config
      - ./cache:/app/cache
      - ./logs:/app/logs
 
      # Quellen (read-only)
      - /mnt/backup-daten:/sources/Daten:ro
      - /mnt/backup-paperless:/sources/Paperless:ro
      - /mnt/backup-homeassistant:/sources/Homeassistant:ro
      - /mnt/backup-kasse:/sources/Kasse:ro
 
      # Restore-Ziel (read-write)
      - /mnt/backup-restore:/restore:rw
 
    command:
      - server
      - start
      - --address=0.0.0.0:51515
      - --insecure
      - --server-username=${KOPIA_UI_USER}
      - --server-password=${KOPIA_UI_PASS}

Hinweis zu --insecure: Kopia spricht dann HTTP ohne eigene TLS-Verschlüsselung. Das ist ok, wenn davor ein Reverse Proxy mit HTTPS-Termination sitzt - was wir empfehlen (z.B. NGIX / TRAEFIK). Ohne Proxy sollte Kopia selbst mit TLS betrieben werden.

Repository im Portunity S3 initialisieren

Das Repository wird einmalig im S3-Speicher vom Portunity secureBackup angelegt. Beispiel:

cd /home/kopia/kopia
 
docker compose run --rm kopia \
  repository create s3 \
  --config-file=/app/config/kopia.config \
  --bucket=MEIN_BUCKET_NAME \
  --endpoint=s3.backup1.portunityhosted.de \
  --region=eu-wup-2 \
  --prefix=kopiahost1

Danach startet ihr Kopia normal:

docker compose up -d

Snapshots & Policies (GFS-Logik)

Kopia-Snapshots werden in der Web-UI erstellt. Wichtig: In der Kopia-UI wählt ihr die Container-Pfade unter /sources/…, nicht die Host-Mounts unter /mnt.

Beispiele:

  • /sources/Homeassistant
  • /sources/Kasse
  • /sources/Paperless
  • /sources/Daten

Empfehlung für Policies:

  • Homeassistant/Kasse: eher häufige Snapshots (z. B. täglich + wöchentlich), da viele kleine Änderungen.
  • Daten/Paperless: täglich + wöchentlich + monatlich (je nach Datenwert).
  • Große Media-Archive: meist auslassen oder separate Strategie.

Restore-Konzept

Restore läuft bewusst über ein separates Ziel (Share Backup_Restore): 1. In Kopia Web-UI Snapshot auswählen 2. Datei/Ordner nach /restore oder /restore/backup-homeassistant-vom-11.12.2033 wiederherstellen 3. Von dort aus gezielt zurück in die Produktiv-Shares kopieren (manuell/skriptgesteuert)

Vorteile:

  • Backup-Host braucht für Quellen nur read-only
  • Restore ist nachvollziehbar und kontrolliert
  • Kein „aus Versehen“ Überschreiben in Produktivpfaden

Automatisierung

Kopia kann Snapshots über die Web-UI als Tasks planen. Alternativ lässt sich per Cron triggern.

Snapshot per Cron anstoßen (Beispiel)

Bauen Sie sich kleine Shell-Scripte und starten Sie diese per cronjob z.B. täglich:

# alle konfigurierten Snapshot-Quellen einmal sichern:
docker compose exec -T kopia kopia snapshot create --all

Oder gezielt. Dies hat den Vorteil verschiedene Backups zu verschiedenen Zeiten starten zu können und dies mit weiteren Backupzyklen abzustimmen (z.B. HomeAssistant sichert auf das NAS um 3 Uhr nachts, von dort geht es um 5 Uhr mit Kopia weiter nach Extern):

docker compose exec -T kopia kopia snapshot create /sources/Homeassistant

Betrieb & Praxis-Tipps

  • Monitoring: regelmäßig ins Kopia UI „Tasks“/„Maintenance“ schauen; Logs liegen zusätzlich im Host-Verzeichnis /home/kopia/kopia/logs.
  • Repository-Passwort sicher verwahren: Ohne KOPIA_PASSWORD ist ein Restore nicht möglich.
  • Netz/Firewall: Port 51515 am Docker-Host nur intern freigeben. Externer Zugriff idealerweise per VPN.
  • TLS für komfortablen Zugriff: Reverse Proxy (z. B. Nginx Proxy Manager) + internes Zertifikat (z. B. Let’s Encrypt via DNS-01 oder interne CA).
  • Dedup/Inkremenz: Kopia arbeitet blockbasiert; wiederkehrende Daten (z. B. ähnliche HA-Backups) werden sehr effizient gespeichert.

Troubleshooting

Kopia startet nicht / Config-Fehler Wenn im Log sowas steht wie „config json … is a directory“: KOPIA_CONFIG_PATH muss eine Datei sein (z. B. /app/config/kopia.config), nicht ein Ordner.

S3 Endpoint Fehler Wenn „Endpoint url cannot have fully qualified paths“: --endpoint darf keinen /bucket enthalten.

Restore scheitert wegen Dateinamen/Path-Limits (SMB) Sehr lange Pfade können auf manchen SMB/NAS Kombinationen Probleme machen. Dann Restore erst nach /restore (lokal oder anderes Ziel) und anschließend mit angepasster Struktur zurückkopieren.

Persönliche Werkzeuge