docs: README.md mit aktueller Projektstruktur und Feature-Übersicht erweitern

This commit is contained in:
2026-04-21 21:43:14 +02:00
parent 3441548066
commit 680c23a61c
+195 -28
View File
@@ -1,41 +1,208 @@
# Darktable Sync 🔄 # darktable-sync
Auto-sync your Darktable database and photos between different computers with a server as intermediate. Keeps local and remote files in sync using rsync over SSH. The wrapper script synchronizes files before launching Darktable and after it closes. The scheduled background synchronization ensures continuous and reliable data exchange — even if the wrapper script is not used. Bidirektionale Synchronisation der Darktable-Datenbank und Fotobibliothek zwischen
einem lokalen Linux-Rechner und einem Server (Synology NAS) via SSH.
Since only file synchronization is performed, only one Darktable instance should run at a time. ## Aktueller Stand
The installation is currently written and tested on (K)Ubuntu 25.04 only. 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.
## Features ✨ ```
- 🔄 Bidirectional sync between local machines and a server darktable_wrapper.sh → Pre-Sync → Darktable starten → Post-Sync
- ⏲️ Automatic sync every 5 minutes via systemd timer darktable_sync.sh → Unison-Sync (DB + Fotos, bidirektional)
- 🖱️ Desktop shortcuts for starting Darktable with sync and sync only darktable_common.sh → Gemeinsame Hilfsfunktionen
- 📊 Desktop notifications ```
## Requirements 📋 Voraussetzungen: Unison (gleiche Version auf Client und Server), SSH-Key-Auth.
- Bash 4+
- rsync ---
- SSH key-based auth to NAS
- systemd (for automatic sync) ## 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 20112021 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 <id> 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.
## Installation 💻
```bash ```bash
git clone https://github.com/MaTr74/darktable-sync.git # 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 cd darktable-sync
cp .env.example .env cp .env.example ~/.config/darktable-sync/.env
nano .env # Edit with your values chmod 600 ~/.config/darktable-sync/.env
chmod +x install.sh uninstall.sh nano ~/.config/darktable-sync/.env
./install.sh ./install.sh
``` ```
## Usage 🚀 ## Konfiguration
- Start via desktop shortcut: "Darktable with Sync"
- Manual sync: Start via desktop shortcut: "Darktable Sync Only"
## Uninstall 🧹 Datei: `~/.config/darktable-sync/.env` (Permissions: 600)
```bash
./uninstall.sh
```
## License 📄 | Variable | Bedeutung |
MIT License - see [LICENSE](LICENSE) |---|---|
| `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