# darktable-sync Bidirektionale Synchronisation der Darktable-Datenbank und Fotobibliothek zwischen einem lokalen Linux-Rechner und einem Server (Synology NAS) via SSH. ## Aktueller Stand Die Skripte synchronisieren DB und Fotos mit **Unison** über SSH. Der Wrapper startet einen Pre-Sync vor und einen Post-Sync nach jedem Darktable-Start. ``` darktable_wrapper.sh → Pre-Sync → Darktable starten → Post-Sync darktable_sync.sh → Unison-Sync (DB + Fotos, bidirektional) darktable_common.sh → Gemeinsame Hilfsfunktionen ``` Voraussetzungen: Unison (gleiche Version auf Client und Server), SSH-Key-Auth. --- ## Architektur-Entscheidungsprotokoll Dieses Dokument hält fest, welche Sync-Ansätze untersucht wurden und warum bestimmte Entscheidungen getroffen oder offengelassen wurden. --- ### Problem 1: Upload-Delete-Safety (rsync --delete) Das ursprüngliche System verwendete `rsync --delete` für den Foto-Upload. Das führt zu einem strukturellen Problem: **rsync kennt keinen Unterschied zwischen:** - Datei lokal gelöscht → soll auch auf Server gelöscht werden ✓ - Datei lokal nie vorhanden (weil ein anderer Client sie hochgeladen hat) → darf NICHT gelöscht werden ✗ **Konkretes Beispiel:** `2025-08_Nordkap_Handy/` existiert nur auf dem Server (von Smartphone hochgeladen), nicht auf dem Laptop. Beim nächsten Upload löscht rsync den gesamten Ordner vom Server — dauerhafter Datenverlust. **Erster Lösungsansatz:** rsync-Manifest — eine Textdatei mit allen zuletzt synchronisierten Pfaden. Beim Upload: fehlt lokal + im Manifest → gelöscht → OK. Fehlt lokal + nicht im Manifest → nie synchronisiert → nicht löschen. **Verworfen**, weil Unison dasselbe Problem architektonisch sauber löst: Unison pflegt intern Archive über den letzten Sync-Zustand und leitet daraus korrekt ab, ob eine fehlende Datei gelöscht oder nie vorhanden war. --- ### Analyse der Sync-Alternativen #### Unison (aktuell implementiert) **Vorteile:** - Internes Archiv löst Upload-Delete-Safety nativ - Triggered Sync (kein Daemon) — passt zur Pre/Post-Sync-Architektur - Transport via SSH, kein zusätzlicher Dienst auf dem Server nötig - Bidirektionaler Sync in einem Aufruf pro Replica-Paar **Konfliktverhalten:** - DB-Konflikte: bestehender Sync-Token-Dialog bleibt erhalten → User entscheidet (`-force local` / `-force remote`) - Foto-Konflikte: `-prefer newer` (neuere Datei gewinnt, kein Dialog) **Kritischer Nachteil: Synology-Installation** Unison erfordert exakt die gleiche Version auf Client und Server — und nicht nur die Unison-Version, sondern auch die zugrundeliegende OCaml-Compiler-Version. Auf einer Synology NAS gibt es kein `apt`. Alle bekannten Anleitungen für Unison auf Synology (Stand 2025) stammen aus 2011–2021 und beschreiben aufwändige Cross-Compilation, die bei jedem DSM-Update erneut erforderlich wird. Entware könnte helfen, aber die Versionskompatibilität ist nicht garantiert. **Unison auf Synology ist ein dauerhaftes Wartungsproblem.** --- #### Syncthing **Vorteile:** - SynoCommunity bietet ein aktiv gepflegtes Paket für DSM 7.x (v2.0.14, Stand 2025) — einfache Installation über Package Center - Kein Versionszwang zwischen Nodes - Upload-Delete-Safety: Syncthing weiß aus seiner eigenen Datenbank, was es synchronisiert hat, und löscht nie Dateien anderer Devices - Transparente Konfliktbehandlung via `.sync-conflict-...`-Dateien - Eingebaute Versionierung (File Versioning) **Nachteil: Always-On-Daemon** Syncthing läuft kontinuierlich. Das kollidiert mit der triggered-sync-Architektur (Pre/Post-Sync um Darktable herum). Das Pausieren via CLI ist technisch möglich (`syncthing cli config folders paused set true/false`), macht die Wrapper-Logik aber komplexer. **Das SQLite-Problem:** Darktable verwendet SQLite im WAL-Modus. Dabei entstehen drei Dateien: `library.db`, `library.db-wal`, `library.db-shm`. Syncthing synct auf Dateiebene ohne SQLite-Semantik zu verstehen. Bei aktivem Sync während Darktable läuft könnte eine inkonsistente DB-Kombination auf der anderen Seite ankommen. Ausserdem erzeugt SQLite-Checkpointing mtime-Updates ohne inhaltliche Änderung — das kann zu Falsch-Konflikten führen. **Lösung für das WAL-Problem:** `.db-wal` und `.db-shm` via `.stignore` ausschließen. Dann synct Syncthing nur `library.db`, die nach Darktable-Beendigung immer konsistent ist (SQLite checkpointed beim Schließen). **Das eigentliche Konflikt-Problem:** Wenn Darktable auf zwei Rechnern unabhängig voneinander läuft und beide eine divergierte `library.db` erzeugen, entsteht ein echter inhaltlicher Konflikt — den kein Sync-Tool automatisch auflösen kann (SQLite-Merging wäre dazu nötig). Syncthing macht diesen Konflikt mit einer `.sync-conflict`-Datei sichtbar, was ehrlicher ist als so zu tun, als könnte man ihn "lösen". --- #### Gegenüberstellung | Kriterium | rsync (original) | Unison (aktuell) | Syncthing | |---|---|---|---| | Upload-Delete-Safety | ✗ (Problem) | ✓ (Archiv) | ✓ (Device-DB) | | Synology-Installation | einfach | sehr schwierig | einfach (SynoCommunity) | | DB-Konflikt-Erkennung | Token + Dialog | Token + Dialog | .sync-conflict-Datei | | DB-Konflikt-Auflösung | User entscheidet | User entscheidet | automatisch (neuere Datei) | | Kein Daemon nötig | ✓ | ✓ | ✗ | | Triggered Sync | ✓ | ✓ | nur mit Pause/Resume | | Foto-Versioning | ✗ | Backup-Dir | ✓ eingebaut | --- ### Offene Architekturentscheidung Es stehen zwei grundlegend verschiedene Ansätze zur Wahl: #### Option A: Script-System beibehalten (Unison) Das bestehende System mit `darktable_sync.sh` bleibt, mit Unison als Sync-Engine. Voraussetzung: Unison muss auf der Synology NAS installierbar sein (Entware oder manuelles Binary). Der Workflow (Pre/Post-Sync, Token-Dialog, Active-Marker, Versions-Check) bleibt erhalten. **Offen:** Ist Unison auf der DS234+ mit einer zum Client kompatiblen Version installierbar? Das muss praktisch getestet werden. #### Option B: Vollständig auf Syncthing umstellen Das gesamte Script-System entfällt. Syncthing übernimmt die Synchronisation dauerhaft. Der `darktable_wrapper.sh` entfällt oder wird auf Pause/Resume-Steuerung reduziert. Das Repo würde zu einem Setup-Guide mit `.stignore`-Template schrumpfen. **Vorteile:** Kein eigener Code zu pflegen, bewährte Software, einfache Synology-Installation. **Nachteile:** Kein expliziter Versions-Check (Darktable-Versionen müssen manuell übereinstimmen), kein Active-Marker (kein Schutz gegen gleichzeitige Nutzung auf mehreren Rechnern), Konflikte werden automatisch statt durch User-Entscheidung aufgelöst. --- ### Empfohlene nächste Schritte 1. Testen: Ist Unison via Entware auf der DS234+ mit kompatibler Version installierbar? - Falls ja → Option A ist machbar - Falls nein → Option B (Syncthing) ist der pragmatische Weg 2. Bei Option B: - Syncthing auf DS234+ via SynoCommunity installieren - `.stignore` für `*.db-wal`, `*.db-shm` konfigurieren - File Versioning in Syncthing aktivieren - Unison-Migration (aktueller Branch) reverten --- ## Installation (aktueller Stand: Unison) Voraussetzung: Unison muss auf Client **und** Server installiert sein, exakt gleiche Version. ```bash # Client (Ubuntu/Debian) sudo apt install unison # Server (Synology) — noch ungeklärt, siehe Architektur-Entscheidungsprotokoll oben git clone https://gitea.troeger-net.org/martin/darktable-sync.git cd darktable-sync cp .env.example ~/.config/darktable-sync/.env chmod 600 ~/.config/darktable-sync/.env nano ~/.config/darktable-sync/.env ./install.sh ``` ## Konfiguration Datei: `~/.config/darktable-sync/.env` (Permissions: 600) | Variable | Bedeutung | |---|---| | `SERVER_IP` | IP oder Hostname des Servers | | `SERVER_USER` | SSH-Benutzer auf dem Server | | `SERVER_SSH_PORT` | SSH-Port (Standard: 22) | | `SERVER_DB_DIR` | Pfad zur Darktable-DB auf dem Server | | `SERVER_PHOTO_DIR` | Pfad zur Fotobibliothek auf dem Server | | `LOCAL_DARKTABLE_DB_DIR` | Lokaler Darktable-DB-Pfad | | `LOCAL_PHOTO_DIR` | Lokaler Fotobibliothek-Pfad | ## Lizenz MIT