Go to file
Stefan Hacker 20e61aa61c Auto-create and chown data dirs on first start
Entrypoint runs as root, ensures /data/{db,uploads,logo} and
/webdav-config exist with UID 1000 ownership, then drops privileges
via gosu. Removes the manual sudo chown step from the README and
makes a fresh docker compose up succeed without prep.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-16 13:20:02 +02:00
public Harden security, polish admin UI and document Windows WebDAV 2026-04-16 12:53:13 +02:00
src Harden security, polish admin UI and document Windows WebDAV 2026-04-16 12:53:13 +02:00
webdav Add file upload portal with per-customer links and WebDAV admin access 2026-04-16 11:00:51 +02:00
windows Document Windows read-only WebDAV quirks and add locking opt-out 2026-04-16 13:11:37 +02:00
.dockerignore first commit 2026-04-16 10:52:20 +02:00
.env.example Harden security, polish admin UI and document Windows WebDAV 2026-04-16 12:53:13 +02:00
.gitignore first commit 2026-04-16 10:52:20 +02:00
Dockerfile Auto-create and chown data dirs on first start 2026-04-16 13:20:02 +02:00
README.md Auto-create and chown data dirs on first start 2026-04-16 13:20:02 +02:00
docker-compose.yml Auto-create and chown data dirs on first start 2026-04-16 13:20:02 +02:00
entrypoint.sh Auto-create and chown data dirs on first start 2026-04-16 13:20:02 +02:00
package.json Harden security, polish admin UI and document Windows WebDAV 2026-04-16 12:53:13 +02:00

README.md

Simple File Upload

Kunden laden Dateien/Ordner über einen individuellen Link hoch (ohne Login). Admin + Sachbearbeiter verwalten Kunden im Adminportal und greifen per WebDAV zu.

Start

cp .env.example .env     # optional: Ports anpassen
docker compose up -d --build
  • Adminportal: http://localhost:3500/
  • WebDAV: webdav://HOST:1900/ (Basic Auth, dieselben Benutzer wie im Adminportal)

Beim ersten Start öffnet sich ein Setup-Wizard — dort legst du den ersten Admin an.

Rollen

  • Admin: legt Kunden + weitere Benutzer (Admins / Sachbearbeiter) an, verwaltet Upload-Links und pro-Kunde-Zugriffe. Hat WebDAV-Vollzugriff auf alles.
  • Sachbearbeiter (Staff): sieht im Adminportal nur die Kunden, auf die ihm der Admin Zugriff erteilt hat. Per WebDAV greift er auf die zugeteilten Kundenordner zu (read oder write).
  • Kunde: kein Login; Upload via individuellem Token-Link (optional mit Passwort + Ablaufdatum). Sieht keine Dateiliste.

Konfiguration

.env (Ports)

Variable Default Zweck
APP_PORT 3500 Host-Port für Adminportal + Upload
WEBDAV_PORT 1900 Host-Port für WebDAV

Admin-GUI → Einstellungen

  • Öffentliche Basis-URL: wird in generierten Upload-Links verwendet. Leer = aus Request ableiten.
  • Cron-Intervall (Minuten): periodischer DB/FS-Abgleich (entfernt verwaiste DB-Einträge von via WebDAV gelöschten Dateien und erfasst direkt per WebDAV hochgeladene Dateien).

Volumes

  • ./data/db/ → SQLite-Datei neben der docker-compose.yml
  • ./data/uploads/ → ein Unterordner pro Kunde (Slug)
  • Named Volume webdav-config → dynamisch generierte Apache-Config

Beide Container laufen als UID 1000:1000. Der App-Container startet kurz als root, korrigiert die Eigentümer der ./data/-Mountpunkte auf 1000:1000 und droppt dann via gosu die Privilegien — fresh deploys laufen also ohne manuellen chown durch.

Wie die WebDAV-ACLs funktionieren

Der App-Container erzeugt bei jeder Benutzer-/Kundenänderung:

  • /webdav-config/htpasswd — alle Benutzer (bcrypt-Hashes direkt aus DB)
  • /webdav-config/access.conf — pro Kundenordner ein <Location>-Block:
    • gleiche Read- und Write-User → ein Require user …
    • unterschiedliche → <Limit GET PROPFIND OPTIONS HEAD> + <LimitExcept …> für saubere Trennung

Der WebDAV-Container (Debian Apache) beobachtet das Verzeichnis via inotifywait und ruft apachectl graceful auf → Änderungen sind in ~2 Sek. wirksam.

Kunden-Upload

  • Datei-Button, Ordner-Button oder Drag & Drop (Dateien und Ordner — Struktur bleibt erhalten).
  • Optional Passwortabfrage, optional Ablaufdatum.
  • Kunde sieht keine Dateiliste, nur eigenes Upload-Feedback.

WebDAV-Zugriff

  • macOS Finder: Gehe zu → Mit Server verbinden → http://HOST:1900/
  • Linux / KDE Dolphin: webdav://<user>@HOST:1900/
  • Windows: siehe Abschnitt unten (einmalige Einrichtung nötig)

Write-Rechte umfassen: PUT, DELETE, MKCOL, MOVE, COPY, PROPPATCH, LOCK, UNLOCK. In Dolphin löscht Shift+Entf direkt (umgeht den nicht existierenden WebDAV-Papierkorb).

Windows als Netzlaufwerk verbinden

Windows verweigert standardmäßig WebDAV via Basic Auth über HTTP und limitiert Dateien auf 50 MB. Beides per Registry erlauben:

  1. windows/enable-webdav-basicauth.reg per Rechtsklick → Zusammenführen (als Administrator) ausführen.

  2. WebClient-Dienst (neu) starten:

    sc config WebClient start=auto
    net stop WebClient
    net start WebClient
    
  3. Verbinden — HTTP-URL ist die saubere Variante (eindeutig WebDAV, keine SMB-Verwechslung). Beispiel mit karlheinz-Credentials, gemountet als Z::

    net use Z: http://HOST:1900/frank-meier /user:karlheinz DEINPW /persistent:yes
    

    Im Explorer „Netzlaufwerk verbinden" → Adresse: http://HOST:1900/ bzw. http://HOST:1900/frank-meier/.

    Alternativ mit UNC-Syntax (intern dasselbe, etwas hakeliger): \\HOST@1900\DavWWWRoot\frank-meier\@1900 und \DavWWWRoot\ sind dabei Pflicht, sonst landest du bei SMB Port 445.

Wenn weiterhin „Ordner nicht gefunden" → meist ist der WebClient-Dienst nicht gestartet oder das Registry-Merge wurde nicht als Administrator ausgeführt.

Bekannte Windows-Eigenheiten bei Read-Only-Zugriff

Hat ein Sachbearbeiter nur Leserechte, zeigt der Windows-Explorer gelegentlich seltsames Verhalten:

  • Entf-Taste „löscht" die Datei optisch — der Server lehnt das DELETE korrekt mit 403 ab, aber der Explorer entfernt das Icon optimistisch. F5 stellt die echte Sicht wieder her.
  • Beim Doppelklick: „Datei existiert nicht, neu erstellen?" — Office & Editoren senden vor dem Öffnen ein LOCK. Bei Read-Only schlägt das mit 403 fehl, das Programm denkt die Datei sei weg. Nach 3060 Sek. (WebClient Negative-Cache läuft aus) klappt es dann meist direkt.

Wenn dich das stört: windows/disable-webdav-locking.reg ausführen — schaltet WebDAV-Locking systemweit ab. Read-Only-Viewing läuft dann sofort und ohne Wartezeit. Trade-off: gemeinsames Bearbeiten ohne Konflikte kann nicht mehr über WebDAV-Locks koordiniert werden.