Go to file
Stefan Hacker 23563622f8 feat: Lock-Badge + smartes Kontextmenue in lokaler Client-Ansicht
Die lokale Dateiliste im Client zeigt jetzt pro Datei ein 🔒-Badge
mit Nutzername wenn ausgecheckt (wie Server-Ansicht + Web-GUI).
browse_sync_folder zieht den Server-Tree bei jedem Aufruf und
korreliert via Journal-Lookup (oder .cloud-Metadaten) die lokale
Datei mit dem File-Lock-Status.

Rechtsklick-Menue reagiert jetzt auf den Lock-Status:
- Frei              -> "Auschecken (sperren)"
- Eigener/fremder   -> "Entsperren (einchecken)"
Neuer Tauri-Command lock_file_cmd fuer reines Sperren ohne Oeffnen.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-12 11:32:01 +02:00
backend fix: Save-Endpoints feuern SSE-Event - Web-Edits synchronisieren sich 2026-04-12 10:56:51 +02:00
clients/desktop feat: Lock-Badge + smartes Kontextmenue in lokaler Client-Ansicht 2026-04-12 11:32:01 +02:00
frontend fix: SSE-Reload in FilesView etwas robuster 2026-04-12 11:21:10 +02:00
.env.example fix: Client-Upload akzeptiert SECRET_KEY oder JWT_SECRET_KEY + Download in Settings 2026-04-11 23:58:54 +02:00
.gitignore fix: build-output/ in .gitignore + aus Git entfernt 2026-04-11 23:55:09 +02:00
CHANGELOG.md docs: CHANGELOG.md - komplette Projekthistorie 2026-04-12 01:52:43 +02:00
Dockerfile fix: SSE-Broadcaster nur 1 Worker - sonst Events zwischen Prozessen verloren 2026-04-12 10:51:49 +02:00
README.md docs: README File Locking Tabelle aktualisiert 2026-04-12 03:06:40 +02:00
build.sh fix: Windows Build laedt Setup-Installer hoch statt nackte .exe 2026-04-12 00:09:32 +02:00
docker-compose.yml feat: OnlyOffice Force-Save bei Ctrl+S + private IP erlauben 2026-04-11 22:54:31 +02:00
nginx.example.conf fix: SSE blockiert gunicorn-Worker - auf gthread umstellen 2026-04-12 10:33:02 +02:00

README.md

Mini-Cloud

Selbstgehostete Web-Cloud-Plattform mit Dateiverwaltung, Kalender, Kontakte, E-Mail-Webclient, Office-Editor und Passwort-Manager.

Features

  • Dateiverwaltung - Upload/Download (Drag & Drop + Ordner-Upload), Berechtigungen, Share-Links (Lesen/Schreiben/Nur-Upload, Passwort, Ablaufdatum), Papierkorb, Ordner als ZIP downloaden
  • Kalender - CalDAV-kompatibel (iOS, DAVx5, Thunderbird, Outlook), iCal-Export, Teilen mit Benutzern
  • Kontakte - CardDAV-kompatibel, vCard-Export, Adressbuecher teilen
  • E-Mail-Webclient - IMAP/SMTP-Proxy (kein eigener Mailserver), Multi-Account, Absender-Logik
  • Office-Editor - DOCX, XLSX, PPTX bearbeiten mit OnlyOffice; PDF, Bilder, Text als Vorschau
  • Passwort-Manager - AES-256-GCM clientseitig verschluesselt, TOTP, Passkeys, KeePass/Firefox/CSV-Import, Ordner teilen
  • Benutzerverwaltung - Rollen (Admin/User), Speicher-Quotas, Einladungslinks, oeffentliche Registrierung an/aus
  • Backup - Lokales ZIP-Backup, SFTP-Backup mit Scheduler + Versionierung, Einzeldatei-Restore
  • Benachrichtigungen - System-Email bei Freigaben, Downloads, neuen Benutzern
  • Sync-API - Delta-Sync fuer Desktop/Mobile-Clients

Tech-Stack

Bereich Technologie
Backend Python / Flask
Frontend Vue 3 / Vite / PrimeVue
Datenbank SQLite (WAL-Modus)
Auth JWT (Web-UI) + HTTP Basic Auth (CalDAV/CardDAV)
Office-Editor OnlyOffice Document Server (optional)

Installation

Voraussetzungen

  • Python 3.11+
  • Node.js 18+
  • npm
  • Docker (fuer Produktion)

Entwicklungsumgebung

# Repository klonen
git clone <repo-url>
cd mini-cloud-datei-email-kalender-kontakte

# .env anlegen
cp .env.example .env
# SECRET_KEY und JWT_SECRET_KEY generieren:
python3 -c "import secrets; print(secrets.token_urlsafe(64))"
# Generierte Werte in .env eintragen

# Backend einrichten
cd backend
python3 -m venv venv
source venv/bin/activate
pip install -r requirements.txt

# Backend starten
python wsgi.py
# -> laeuft auf http://localhost:5000 (nur API, nicht im Browser oeffnen)

# Frontend einrichten (neues Terminal)
cd frontend
npm install

# Frontend starten
npm run dev
# -> laeuft auf http://localhost:3100

Wichtig - Ports in der Entwicklung:

Port Dienst Im Browser oeffnen?
5000 Backend (Flask API) Nein - nur API, kein Frontend
3100 Frontend (Vite Dev Server) Ja - hier arbeiten!

Im Entwicklungsmodus immer http://localhost:3100 im Browser oeffnen. Der Vite Dev Server leitet API-Aufrufe automatisch an Port 5000 weiter (Proxy in vite.config.js).

In der Docker-Produktion laeuft alles auf einem einzigen Port (5000) - Backend liefert das gebaute Frontend direkt mit aus.

Beim ersten Registrieren wird der Benutzer automatisch zum Admin.

Docker (Produktion)

# .env anlegen und Secrets eintragen
cp .env.example .env
# SECRET_KEY und JWT_SECRET_KEY generieren und eintragen:
python3 -c "import secrets; print(secrets.token_urlsafe(64))"

# Starten
docker-compose up --build -d

Die Datenbank und hochgeladene Dateien liegen unter ./data/ (Bind Mount, keine Docker Volumes).

Docker aufraeumen (Speicher freigeben)

Nach vielen Builds sammeln sich alte Images und Cache-Layer an:

# Alles Ungenutzte loeschen (Images, Container, Cache, Netzwerke):
docker system prune -a -f

# Nur alte/ungenutzte Images loeschen:
docker image prune -a -f

# Nur Build-Cache loeschen:
docker builder prune -a -f

# Speicherverbrauch anzeigen:
docker system df

Bei Problemen nach Updates (alte Frontend-Version etc.):

docker-compose down
docker-compose build --no-cache
docker-compose up -d

Nginx Reverse-Proxy (Beispiel)

Die Datei nginx.example.conf enthaelt eine vollstaendige Beispielkonfiguration:

# cloud.example.com -> Mini-Cloud (Port 5000)
server {
    listen 443 ssl http2;
    server_name cloud.example.com;
    ssl_certificate /etc/letsencrypt/live/cloud.example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/cloud.example.com/privkey.pem;
    client_max_body_size 0;

    location / {
        proxy_pass http://127.0.0.1:5000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

Let's Encrypt Zertifikat erstellen:

certbot --nginx -d cloud.example.com

OnlyOffice Document Server

Fuer die Bearbeitung von Word, Excel und PowerPoint Dateien direkt im Browser. OnlyOffice benoetigt eine eigene Subdomain mit HTTPS.

1. .env - OnlyOffice URL setzen:

ONLYOFFICE_URL=https://office.example.com

Das JWT-Secret wird automatisch vom JWT_SECRET_KEY verwendet - kein extra Secret noetig.

2. docker-compose.yml - OnlyOffice-Service aktivieren:

Der OnlyOffice-Service ist in der docker-compose.yml bereits vorbereitet. Er nutzt den gleichen JWT_SECRET_KEY aus der .env.

3. Nginx - Eigene Subdomain fuer OnlyOffice:

server {
    listen 443 ssl http2;
    server_name office.example.com;
    ssl_certificate /etc/letsencrypt/live/office.example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/office.example.com/privkey.pem;

    location / {
        proxy_pass http://127.0.0.1:8080;
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
    }
}

4. Starten:

certbot --nginx -d office.example.com
docker-compose up --build -d

Ohne OnlyOffice (ONLYOFFICE_URL leer) werden Office-Dateien in einer einfachen Vorschau angezeigt. Mit OnlyOffice erhaelt man einen vollwertigen Editor (wie Google Docs).

Verwendung

Dateien

  • Dateien per Drag-and-Drop oder Upload-Button hochladen
  • Ganze Ordner mit Unterordnern hochladen (Drag & Drop oder Ordner-Button)
  • Ordner erstellen, Dateien verschieben/umbenennen
  • Ordner als ZIP herunterladen
  • Geloeschte Dateien landen im Papierkorb (wiederherstellen oder endgueltig loeschen)
  • Share-Links erstellen mit drei Berechtigungsstufen:
    • Nur Lesen - Download, Ordnerinhalt sehen
    • Lesen + Schreiben - Download, Upload, Loeschen
    • Nur Upload - Hochladen ohne Einblick (Briefkasten-Modus)
  • Optional: Passwort und Ablaufdatum fuer Share-Links
  • Dateien/Ordner mit anderen Benutzern teilen (Lesen/Schreiben/Admin)
  • Gruenes Icon zeigt an welche Dateien bereits Freigaben haben

Kalender

  • Kalender erstellen, Events anlegen (Monats-/Tagesansicht)
  • Kalender mit anderen Benutzern teilen (Lesen oder Lesen+Schreiben)
  • iCal-Link generieren fuer Read-Only-Import in Google Calendar, Apple Kalender etc.
  • CalDAV-Zugriff fuer native Sync:
    • iOS: Einstellungen > Kalender > Accounts > Anderer > CalDAV
    • Android (DAVx5): Server-URL: https://<deine-domain>/dav/
    • Thunderbird: Neuer Kalender > Im Netzwerk > CalDAV
    • Outlook (CalDAV-Synchronizer): Server-URL: https://<deine-domain>/dav/

Kontakte

  • Adressbuecher anlegen, Kontakte erstellen/bearbeiten
  • Adressbuecher mit anderen Benutzern teilen
  • vCard-Export fuer Backup
  • CardDAV-Zugriff analog zum Kalender

E-Mail

  • E-Mail-Konten unter Einstellungen hinzufuegen (IMAP/SMTP-Zugangsdaten)
  • Admin kann E-Mail-Konten fuer andere Benutzer anlegen
  • Kein eigener Mailserver noetig - verbindet sich mit externen Mailservern
  • Bei keinem konfigurierten Konto wird der E-Mail-Bereich ausgeblendet
  • Mehrere Konten: Ordner nach Konten gruppiert, Standard-Absender = aktives Konto

Office-Dateien

  • Doppelklick oder Auge-Icon oeffnet die Vorschau
  • Mit OnlyOffice: Vollwertiger Editor fuer DOCX, XLSX, PPTX (wie Google Docs)
  • Ohne OnlyOffice: Einfache Vorschau (HTML/Tabelle/Folien), Text-Dateien bearbeitbar
  • PDF wird inline angezeigt, Bilder mit Vorschau

Passwort-Manager

  • Alle Daten clientseitig mit AES-256-GCM verschluesselt (Zero Knowledge)
  • TOTP-Codes direkt generieren
  • Passwort-Generator integriert
  • Import aus: KeePass (.kdbx), Firefox (CSV), Chrome/Bitwarden/1Password (CSV)
  • Ordner/Gruppen wie in KeePass
  • Einzelne Passwoerter oder ganze Ordner mit anderen Benutzern teilen

Backup & Restore

  • Lokales Backup: ZIP-Download mit Datenbank + allen Dateien
  • SFTP-Backup: Automatisch auf SFTP-Server sichern
    • Mehrere Backup-Ziele moeglich
    • Konfigurierbares Intervall (15 Min. bis woechentlich)
    • Versionierung mit automatischem Aufraumen
    • Versionen durchsuchen und Einzeldateien wiederherstellen
  • Restore: ZIP hochladen (Chunked Upload fuer grosse Backups) oder direkt von SFTP

Administration

  • Benutzer anlegen, bearbeiten, deaktivieren, loeschen
  • Benutzersuche
  • E-Mail-Konten pro Benutzer verwalten
  • Oeffentliche Registrierung an/aus
  • Einladungslinks (funktionieren auch bei deaktivierter Registrierung)
  • System-Email (SMTP) fuer Benachrichtigungen und Einladungen

Projektstruktur

backend/
  app/
    api/          # REST-Endpunkte
    models/       # SQLAlchemy-Models
    services/     # Business-Logik (Crypto, SFTP, Email, Scheduler)
    dav/          # CalDAV/CardDAV (Radicale-Vorbereitung)
  wsgi.py         # Einstiegspunkt

frontend/
  src/
    views/        # Vue-Seiten
    components/   # Wiederverwendbare Komponenten
    stores/       # Pinia State Management
    api/          # Axios API-Client
    router/       # Vue Router

data/             # Laufzeitdaten (gitignored)
  minicloud.db    # SQLite-Datenbank
  files/          # Hochgeladene Dateien

Desktop Sync Client

Der Desktop-Client (clients/desktop/) synchronisiert Dateien zwischen der Cloud und einem lokalen Ordner. Gebaut mit Tauri 2 (Rust + Vue).

Features

  • Multi-Sync-Pfade: Beliebig viele Server-Ordner auf lokale Ordner mappen (z.B. /Projekte -> ~/Projekte, /Shared/Team -> ~/Team)
  • Virtual Files: .cloud-Platzhalter (0 Bytes), Download erst bei Doppelklick. Kein Speicherverbrauch fuer nicht benoetigte Dateien
  • Full Sync: Alternativ alle Dateien komplett lokal spiegeln (pro Pfad waehlbar)
  • Offline-Markierung: Einzelne Dateien als offline verfuegbar markieren (Rechtsklick im Datei-Browser)
  • Sofort-Sync: Filesystem-Watcher erkennt lokale Aenderungen sofort (3s Debounce), kein Polling
  • Intelligenter Sync: Checksum-Tracking erkennt wer sich geaendert hat (Server oder Lokal)
  • Konflikt-Erkennung: Bei gleichzeitiger Aenderung wird eine Konflikt-Kopie erstellt
  • File Locking: Lock beim Oeffnen, Heartbeat alle 60s, manuelles Entsperren per Rechtsklick, auto-unlock nach 15 Min ohne Heartbeat
  • System-Tray: Minimiert in den Tray statt zu beenden, Doppelklick oeffnet Fenster
  • Minimiert starten: Optional direkt im Tray starten (Checkbox in Einstellungen)
  • Auto-Login: Zugangsdaten und Sync-Pfade bleiben nach Neustart/Update erhalten
  • Terminalserver: Pro User eine eigene Instanz, keine Konflikte zwischen Benutzern
  • .cloud Datei-Handler: Doppelklick im Explorer oeffnet ueber den Client

Terminalserver-Verhalten

Szenario Verhalten
User A startet Client Laeuft, eigenes Lock-File in %APPDATA%\MiniCloud Sync\
User B startet Client Laeuft separat, eigenes Lock-File in seinem %APPDATA%
User A doppelklickt .cloud Laufende Instanz von User A oeffnet die Datei
User A startet nochmal "Already running" -> beendet sich sofort
Client crashed Naechster Start prueft ob PID noch lebt -> stale Lock -> ueberschreibt

Virtual Files vs. Full Sync

Virtual Files Full Sync
Speicher Nur .cloud Platzhalter (0 Bytes) Alle Dateien komplett lokal
Zugriff Doppelklick = Download + Oeffnen Sofort verfuegbar
Offline Nur markierte Dateien Alles offline
Upload Neue lokale Dateien werden hochgeladen Bidirektionaler Sync
Empfehlung Grosse Datenmengen, Laptops Kleine Ordner, immer offline noetig

Sync-Logik (Checksum-Tracking)

Der Client merkt sich den Checksum jeder Datei beim letzten Sync. Beim naechsten Sync wird verglichen wer sich geaendert hat:

Lokal geaendert Server geaendert Aktion
Nein Ja Server -> Lokal (Download)
Ja Nein Lokal -> Server (Upload)
Ja Ja Konflikt: Lokale Datei wird zu Datei (Konflikt).txt, Server-Version wird heruntergeladen
Nein Nein Nichts (identisch)

Beim ersten Sync (kein gespeicherter Checksum) gewinnt immer der Server.

File Locking

Dateien werden beim Oeffnen ueber den Client automatisch auf dem Server gesperrt. Andere Benutzer sehen "Datei gesperrt von X" und koennen sie nicht bearbeiten.

Szenario Was passiert
.cloud Datei oeffnen Download + Lock + Heartbeat alle 60s
Fertig -> Rechtsklick "Entsperren" Lock sofort aufgehoben
Rechtsklick "Nicht mehr offline" Lock aufgehoben + zurueck zu .cloud
Client beenden ohne Entsperren Kein Heartbeat -> Lock laeuft nach 15 Min ab
Laptop zugeklappt / Netzwerk weg Kein Heartbeat -> Lock laeuft nach 15 Min ab
Admin im Web-UI Kann jeden Lock jederzeit manuell loesen

Bauen

# Voraussetzung: Docker

# Linux:
./build.sh linux

# Windows (Cross-Compile):
./build.sh windows

# macOS (nur auf Mac):
./build.sh mac

# Alle Desktop-Plattformen:
./build.sh all-desktop

Auto-Upload auf den Server

Nach dem Build wird der Client automatisch auf den Cloud-Server hochgeladen und steht dort zum Download bereit.

Auf der Entwicklungsmaschine (nicht auf dem Server!) in die .env eintragen:

# URL der Cloud-Instanz
CLOUD_URL=https://cloud.example.com

# SECRET_KEY des Zielservers (identisch mit SECRET_KEY in der Server-.env)
BUILD_UPLOAD_TOKEN=der-secret-key-vom-server

Danach laedt ./build.sh linux (etc.) den Build automatisch hoch. Auf der Login-Seite erscheint dann "Desktop & Mobile Clients herunterladen".

Wichtig: CLOUD_URL und BUILD_UPLOAD_TOKEN gehoeren NUR in die .env der Entwicklungsmaschine, NICHT auf den Produktionsserver!

Einstellungen

Einstellungen werden gespeichert in:

  • Windows: %APPDATA%\MiniCloud Sync\config.json
  • Linux: ~/.config/MiniCloud Sync/config.json
  • macOS: ~/Library/Application Support/MiniCloud Sync/config.json

Gespeichert werden: Server-URL, Benutzername, Passwort (base64), Sync-Pfade. Bleiben bei Updates erhalten.

Roadmap

  • Mobile Sync-Client (iOS, Android) mit On-Demand-Download + File Provider
  • Native Passwort-Manager Clients mit Autofill und Biometrie
  • Radicale-Integration fuer vollstaendiges CalDAV/CardDAV-Protokoll

Lizenz

Privates Projekt.