From e385a44fb9fa9581ed45250c81c387c2e6d3b91c Mon Sep 17 00:00:00 2001 From: Sandro Date: Thu, 29 Oct 2026 22:51:57 +0100 Subject: [PATCH] chore(docker): explanations in .env.example, whisper as commented block - docker-compose.yml only maps variables; every variable is explained in .env.example (German, with defaults, units and choices). - The whisper service is a commented block to switch on instead of a compose profile. - TZ, TRUSTED_PROXIES, LOGIN_PROTECTION, DEMO_RESET_MINUTES and LEGAL_*_CONTENT are now passed through (they had no effect from .env). Co-Authored-By: Claude Opus 5.5 --- .env.example | 109 +++++++++++++++++++++++++++++++++++-------- CHANGELOG.md | 3 +- Doku/architecture.md | 2 +- README.md | 2 + docker-compose.yml | 81 ++++++++++++++++---------------- 5 files changed, 136 insertions(+), 61 deletions(-) diff --git a/.env.example b/.env.example index 87a7662..1923548 100644 --- a/.env.example +++ b/.env.example @@ -1,43 +1,112 @@ -# MindSift Environment Configuration -PORT=8080 -DATA_DIR=/data -DATABASE_URL=sqlite:///data/mindsift.db -JWT_SECRET=change_this_to_a_secure_random_key_min_32_chars -BASE_URL=http://localhost:8080 -ALLOW_REGISTRATION=false -# Logging level: debug, info, warn, error (Default: info) -LOG_LEVEL=info -# LOG_LEVEL=debug -# DEBUG=true +# MindSift – Einstellungen +# Kopieren nach .env (cp .env.example .env) und anpassen; docker-compose.yml liest die Werte von dort. +# Leer gelassene Werte nehmen den Standard aus docker-compose.yml. Nach Änderungen: docker compose up -d -# Optional SMTP Server Configuration for Email Alarms (can also be set in Admin Settings UI) +# ─── Grundeinstellungen ──────────────────────────────────────────────────────────────────────────── + +# Port auf dem Host, unter dem MindSift erreichbar ist (im Container immer 8080). +PORT=8080 + +# Geheimer Schlüssel für die Anmeldung, mindestens 32 zufällige Zeichen, z. B. von: openssl rand -hex 32 +# Bekannte Beispielwerte (wie dieser) werden ignoriert; dann erzeugt MindSift selbst einen und legt ihn in data/ ab.. +JWT_SECRET=change_this_to_a_secure_random_key_min_32_chars + +# Öffentliche Adresse der Instanz, so wie sie im Browser aufgerufen wird. Wird für Links in E-Mails +# (Passwort zurücksetzen) gebraucht und beschränkt, von welcher Adresse Live-Verbindungen kommen dürfen. +BASE_URL=http://localhost:8080 + +# Zeitzone für Fälligkeiten und Alarme (Standard Europe/Berlin). +TZ=Europe/Berlin + +# true = jeder darf sich ein Konto anlegen; false = nur mit Einladungscode vom Admin. +# Lässt sich später in Administration → Server & Isolation ändern. +ALLOW_REGISTRATION=false + +# ─── Sicherheit ──────────────────────────────────────────────────────────────────────────────────── + +# Wessen Angaben zur Besucher-Adresse (X-Forwarded-For / X-Real-IP) geglaubt werden. Wichtig für die +# Login-Sperre hinter einem Reverse-Proxy. +# private Proxys im lokalen Netz, Docker-Netz oder Tailscale (Standard, passt für die meisten Setups) +# none keinem Proxy glauben (MindSift direkt im Internet) +# all jedem glauben (schaltet die Prüfung ab) +# Liste zusätzlich eigene Adressen, z. B. private,203.0.113.0/24 (Cloudflare und andere externe Proxys) +TRUSTED_PROXIES=private + +# Sperre nach Fehlversuchen beim Login und Limits für Registrierung und „Passwort vergessen“. +# false schaltet beides ab (nur sinnvoll, wenn ein vorgeschalteter Dienst das übernimmt). +LOGIN_PROTECTION=true + +# ─── Protokoll ───────────────────────────────────────────────────────────────────────────────────── + +# Wie ausführlich das Container-Log ist: debug, info, warn oder error. +LOG_LEVEL=info +# true = ausführliches Protokoll aller Anfragen und der Synchronisation (wie LOG_LEVEL=debug). +DEBUG=false + +# ─── Demo ────────────────────────────────────────────────────────────────────────────────────────── + +# true = öffentliche Demo: legt die Konten admin/admin und user/user mit Beispieldaten an. Die Demo +# verschickt nichts (keine Mails, Webhooks, Alarme) und schützt die gemeinsam genutzten Konten. +MINDA_DEMO=false +# Nur in der Demo: alle so viele Minuten auf die Beispieldaten zurücksetzen (0 = nie). +DEMO_RESET_MINUTES=20 + +# ─── E-Mail (optional) ───────────────────────────────────────────────────────────────────────────── +# Für Alarm-Mails und „Passwort vergessen“. Lässt sich alternativ in Administration → E-Mail einstellen; +# Werte dort haben Vorrang. + +# Mailserver, z. B. smtp.example.com. Leer = kein Mailversand. SMTP_HOST= +# 587 (STARTTLS) oder 465 (TLS ab Verbindungsbeginn). SMTP_PORT=587 +# Anmeldung am Mailserver; leer, wenn der Server keine verlangt. SMTP_USER= SMTP_PASS= -SMTP_FROM=noreply@mindsift.local +# Absenderadresse, z. B. MindSift . Leer = SMTP_USER bzw. noreply@mindsift.local. +SMTP_FROM= +# true = nur verschlüsselt senden. SMTP_TLS=true -# Only for internal mail servers with self-signed certificates +# true = selbstsignierte Zertifikate akzeptieren (nur für interne Mailserver). SMTP_SKIP_VERIFY=false -# Optional legal notices: external link and/or Markdown (inline or as file path) +# ─── Impressum und Datenschutz (optional) ────────────────────────────────────────────────────────── +# Werden auf der Anmeldeseite und in den Einstellungen verlinkt. Entweder als Link auf eine externe +# Seite (nur http/https) oder als Markdown-Text, direkt hier oder als Datei (per Volume einbinden). +# Ohne Angaben bleiben die Links unsichtbar. LEGAL_IMPRINT_URL= LEGAL_PRIVACY_URL= +LEGAL_IMPRINT_CONTENT= +LEGAL_PRIVACY_CONTENT= +# Pfad im Container, z. B. /legal/impressum.md LEGAL_IMPRINT_CONTENT_FILE= LEGAL_PRIVACY_CONTENT_FILE= -# Optional: own speech recognition (Whisper). Without STT_URL the browser's recognition is used. -# Enable: STT_URL=http://whisper:8000 and COMPOSE_PROFILES=whisper (starts the "whisper" service), -# then: mkdir -p whisper && sudo chown 1000:1000 whisper && docker compose up -d -# COMPOSE_PROFILES=whisper +# ─── Spracherkennung (optional) ──────────────────────────────────────────────────────────────────── +# Ohne STT_URL nutzt MindSift die Spracherkennung des Browsers (Chrome, Edge, Safari; die Aufnahme geht +# dabei an Google, Microsoft bzw. Apple). Mit eigenem Whisper-Server bleibt alles auf deinem Server und +# es funktioniert in allen Browsern. Dazu den Block „whisper“ in docker-compose.yml einkommentieren +# (Anleitung steht dort). Fehler stehen im Log: docker compose logs mindsift whisper + +# Adresse des Whisper-Servers (OpenAI-kompatibel, z. B. speaches). Gesetzt = Server-Modus. STT_URL= +# Modell: deepdml/faster-whisper-large-v3-turbo-ct2 (beste Erkennung, ca. 2 GB RAM, langsamer) +# Systran/faster-whisper-small (ca. 1 GB RAM, deutlich schneller, kleine Fehler) STT_MODEL=deepdml/faster-whisper-large-v3-turbo-ct2 +# Sprachcode, z. B. de oder en; auto = automatisch erkennen. STT_LANGUAGE=de +# Nur falls der Whisper-Server einen Schlüssel verlangt (bei speaches: dessen API_KEY). STT_API_KEY= +# true = Mikrofon überall ausblenden, auch die Browser-Erkennung. STT_DISABLED=false -# Limits (server mode) + +# Schutzwerte für den Server-Modus +# Längste Aufnahme in Sekunden; danach beendet der Browser die Aufnahme selbst. STT_MAX_SECONDS=600 +# Größte Aufnahme in MB. STT_MAX_UPLOAD_MB=25 +# Wie viele Erkennungen gleichzeitig laufen; weitere warten in der Schlange. 1 schont schwache CPUs. STT_MAX_PARALLEL=1 +# Erkennungen pro Person und Stunde. STT_PER_USER_PER_HOUR=60 +# Höchstdauer einer Erkennung in Sekunden, Warten in der Schlange eingeschlossen. STT_TIMEOUT_SECONDS=120 diff --git a/CHANGELOG.md b/CHANGELOG.md index f65ee62..53bd45c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,11 +7,12 @@ Das Format folgt [Keep a Changelog](https://keepachangelog.com/de/1.1.0/), die V ## [Unreleased] ### Added -- Eigene Spracherkennung (optional): Mit `STT_URL` schickt MindSift Aufnahmen an einen selbst betriebenen Whisper-Server (OpenAI-kompatibel, z. B. speaches) statt an Google oder Microsoft. Einstellung nur per Umgebungsvariablen (`STT_*`) inklusive Grenzwerten; `docker-compose.yml` bringt den Dienst `whisper` als Profil mit, das Modell lädt MindSift beim ersten Start selbst. Administration → Server & Isolation zeigt den aktiven Modus und bietet eine Testaufnahme. In der Demo bleibt es bei der Browser-Erkennung. +- Eigene Spracherkennung (optional): Mit `STT_URL` schickt MindSift Aufnahmen an einen selbst betriebenen Whisper-Server (OpenAI-kompatibel, z. B. speaches) statt an Google oder Microsoft. Einstellung nur per Umgebungsvariablen (`STT_*`) inklusive Grenzwerten; `docker-compose.yml` enthält den Dienst `whisper` als auskommentierten Block zum Einschalten, das Modell lädt MindSift beim ersten Start selbst. Administration → Server & Isolation zeigt den aktiven Modus und bietet eine Testaufnahme. In der Demo bleibt es bei der Browser-Erkennung. - API: `POST /voice/transcribe`, `GET /admin/voice`; `/auth/status` meldet `voice.mode`. - Code-Blöcke in Notizen: Sprachauswahl (rund 50 Sprachen, bei Bedarf nachgeladen), Farben beim Tippen im Stil von VS Code Dark+/Light+ für alle Themes, „Kopieren“, Tab/Shift+Tab rückt ein und aus. `/code yaml` oder ```` ```yaml ```` legt die Sprache direkt fest. ### Changed +- `docker-compose.yml` enthält nur noch die Zuordnungen; alle Erklärungen zu den Variablen stehen in `.env.example`. Neu durchgereicht werden `TZ`, `TRUSTED_PROXIES`, `LOGIN_PROTECTION`, `DEMO_RESET_MINUTES` und `LEGAL_*_CONTENT`, die vorher in `.env` gesetzt wirkungslos blieben. - Workspace-Seitenleiste wie ein Datei-Explorer: angeheftete Notizen oben, darunter Ordner und Notizen ohne Zwischenüberschriften. - Spracheingabe in Quick Dump, im mobilen Erfassen-Sheet und beim Halten des +-Knopfs folgt der Server-Einstellung: mit eigenem Whisper-Server funktioniert sie in allen Browsern (auch Firefox), mit Live-Wellen während der Aufnahme und „Wird erkannt…“ danach. Ohne Unterstützung im Browser oder mit `STT_DISABLED=true` ist das Mikrofon ausgeblendet statt einer Fehlermeldung. diff --git a/Doku/architecture.md b/Doku/architecture.md index db7916d..b3d2644 100644 --- a/Doku/architecture.md +++ b/Doku/architecture.md @@ -94,7 +94,7 @@ Hinweis: `DATABASE_URL` mit `postgres…` führt dazu, dass der Standardpfad in Nur über Umgebungsvariablen (`STT_*`, siehe oben), nicht in der Oberfläche; Administration → Server & Isolation zeigt den aktiven Modus, den Zustand des Whisper-Servers und bietet eine Testaufnahme. Alle Mikrofon-Knöpfe (Quick-Dump-Leiste, mobiles Erfassen-Sheet, Halten des +-Knopfs) nutzen denselben Hook `useVoiceInput` (`frontend/src/lib/voice.ts`, `useVoiceInput.ts`): `server` nimmt auf und zeigt „Wird erkannt…“, `browser` liefert Text schon beim Sprechen, `off` oder ein Browser ohne die nötige Funktion blendet das Mikrofon aus. Im Server-Modus zeigen Wellen den echten Mikrofonpegel (`VoiceWave`), die Aufnahme endet spätestens nach `STT_MAX_SECONDS`. Der Browser nimmt per `MediaRecorder` auf (WebM/Opus, in Safari MP4/AAC) und schickt die Aufnahme an `POST /voice/transcribe`; MindSift reicht sie an `STT_URL/v1/audio/transcriptions` weiter (`model`, `language`) und gibt nur den Text zurück. Nichts wird gespeichert oder protokolliert außer Fehlern (`internal/api/voice.go`). Beim Start wartet MindSift auf den Whisper-Server und stößt den Download des Modells an, falls es fehlt (`POST /v1/models/` bei speaches). -Docker Compose bringt den optionalen Dienst `whisper` (speaches 0.8.3, CPU, Profil `whisper`) mit; das Modell liegt in `./whisper` (Ordner gehört UID 1000). Gemessen auf einem Desktop mit 16 Kernen (int8) für einen Satz von 4 s: `Systran/faster-whisper-small` 1,6 s, `deepdml/faster-whisper-large-v3-turbo-ct2` 8 s bei besserer Erkennung (RAM ca. 1 bzw. 2 GB). Auf geteilten vCPUs ist mit dem Mehrfachen zu rechnen. +`docker-compose.yml` enthält den Dienst `whisper` (speaches 0.8.3, CPU) als auskommentierten Block: Rauten entfernen, `STT_URL=http://whisper:8000` in `.env` setzen, `docker compose up -d`; das Modell liegt in `./whisper` (Ordner gehört UID 1000). Gemessen auf einem Desktop mit 16 Kernen (int8) für einen Satz von 4 s: `Systran/faster-whisper-small` 1,6 s, `deepdml/faster-whisper-large-v3-turbo-ct2` 8 s bei besserer Erkennung (RAM ca. 1 bzw. 2 GB). Auf geteilten vCPUs ist mit dem Mehrfachen zu rechnen. ## Hintergrundjob: Alarme diff --git a/README.md b/README.md index f4b445d..70032a2 100644 --- a/README.md +++ b/README.md @@ -123,6 +123,8 @@ curl -fsSL https://git.dsit.me/sandrodach/MindSift/raw/branch/dev/.env.example - docker compose up -d ``` +Alle Einstellungen stehen mit Erklärung in `.env`. Optional kommt eine eigene Spracherkennung dazu: Block `whisper` in `docker-compose.yml` einkommentieren und `STT_URL=http://whisper:8000` setzen (Anleitung in der Datei). + Minimal: ```yaml diff --git a/docker-compose.yml b/docker-compose.yml index e37bd3d..0d55d77 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,3 +1,6 @@ +# MindSift – Docker Compose +# Eingestellt wird alles in der Datei .env neben dieser Datei. Was jede Variable bewirkt, steht in +# .env.example (kopieren: cp .env.example .env). Hier stehen nur die Zuordnungen mit Standardwerten. services: mindsift: image: git.dsit.me/sandrodach/mindsift:dev @@ -10,16 +13,17 @@ services: environment: - PORT=8080 - DATA_DIR=/data + - TZ=${TZ:-Europe/Berlin} - JWT_SECRET=${JWT_SECRET:-change_this_to_a_secure_random_key_min_32_chars} - BASE_URL=${BASE_URL:-http://localhost:8080} - ALLOW_REGISTRATION=${ALLOW_REGISTRATION:-false} + - TRUSTED_PROXIES=${TRUSTED_PROXIES:-private} + - LOGIN_PROTECTION=${LOGIN_PROTECTION:-true} - LOG_LEVEL=${LOG_LEVEL:-info} - # Set LOG_LEVEL=debug or DEBUG=true for detailed request and sync logging - # - LOG_LEVEL=debug - # - DEBUG=true - # Demo mode: if true, automatically seeds demo accounts admin/admin and user/user + - DEBUG=${DEBUG:-false} - MINDA_DEMO=${MINDA_DEMO:-false} - # Optional SMTP / Mail Configuration (can also be configured in Admin UI) + - DEMO_RESET_MINUTES=${DEMO_RESET_MINUTES:-20} + # E-Mail - SMTP_HOST=${SMTP_HOST:-} - SMTP_PORT=${SMTP_PORT:-587} - SMTP_USER=${SMTP_USER:-} @@ -27,42 +31,41 @@ services: - SMTP_FROM=${SMTP_FROM:-} - SMTP_TLS=${SMTP_TLS:-true} - SMTP_SKIP_VERIFY=${SMTP_SKIP_VERIFY:-false} - # Optional: Impressum / Datenschutz (URL oder Markdown-Datei, z. B. per Volume eingebunden) + # Impressum / Datenschutz - LEGAL_IMPRINT_URL=${LEGAL_IMPRINT_URL:-} - LEGAL_PRIVACY_URL=${LEGAL_PRIVACY_URL:-} + - LEGAL_IMPRINT_CONTENT=${LEGAL_IMPRINT_CONTENT:-} + - LEGAL_PRIVACY_CONTENT=${LEGAL_PRIVACY_CONTENT:-} - LEGAL_IMPRINT_CONTENT_FILE=${LEGAL_IMPRINT_CONTENT_FILE:-} - LEGAL_PRIVACY_CONTENT_FILE=${LEGAL_PRIVACY_CONTENT_FILE:-} - # Optional: eigene Spracherkennung (Whisper, siehe Dienst "whisper" unten). Ohne STT_URL nutzt - # MindSift die Spracherkennung des Browsers. Alles nur hier einstellbar, nicht in der Oberfläche; - # Probleme stehen im Log (docker compose logs mindsift whisper). - - STT_URL=${STT_URL:-} # z. B. http://whisper:8000 – gesetzt = Server-Modus - - STT_MODEL=${STT_MODEL:-deepdml/faster-whisper-large-v3-turbo-ct2} # kleiner/schneller: Systran/faster-whisper-small - - STT_LANGUAGE=${STT_LANGUAGE:-de} # Sprachcode, "auto" = automatisch erkennen - - STT_API_KEY=${STT_API_KEY:-} # nur falls der Whisper-Server einen verlangt (API_KEY dort) - - STT_DISABLED=${STT_DISABLED:-false} # true = Mikrofon überall ausblenden - # Schutzwerte für den Server-Modus - - STT_MAX_SECONDS=${STT_MAX_SECONDS:-600} # längste Aufnahme in Sekunden (danach stoppt der Browser) - - STT_MAX_UPLOAD_MB=${STT_MAX_UPLOAD_MB:-25} # größte Aufnahme in MB - - STT_MAX_PARALLEL=${STT_MAX_PARALLEL:-1} # gleichzeitige Erkennungen, weitere warten in der Schlange - - STT_PER_USER_PER_HOUR=${STT_PER_USER_PER_HOUR:-60} # Erkennungen pro Benutzer und Stunde - - STT_TIMEOUT_SECONDS=${STT_TIMEOUT_SECONDS:-120} # Höchstdauer pro Erkennung inkl. Warten + # Spracherkennung + - STT_URL=${STT_URL:-} + - STT_MODEL=${STT_MODEL:-deepdml/faster-whisper-large-v3-turbo-ct2} + - STT_LANGUAGE=${STT_LANGUAGE:-de} + - STT_API_KEY=${STT_API_KEY:-} + - STT_DISABLED=${STT_DISABLED:-false} + - STT_MAX_SECONDS=${STT_MAX_SECONDS:-600} + - STT_MAX_UPLOAD_MB=${STT_MAX_UPLOAD_MB:-25} + - STT_MAX_PARALLEL=${STT_MAX_PARALLEL:-1} + - STT_PER_USER_PER_HOUR=${STT_PER_USER_PER_HOUR:-60} + - STT_TIMEOUT_SECONDS=${STT_TIMEOUT_SECONDS:-120} - # Optionale Spracherkennung auf dem eigenen Server (speaches mit faster-whisper, nur CPU). - # Start: in .env STT_URL=http://whisper:8000 und COMPOSE_PROFILES=whisper setzen, dann - # mkdir -p whisper && sudo chown 1000:1000 whisper (der Container läuft als UID 1000) - # docker compose up -d - # Das Modell (large-v3-turbo ca. 1,6 GB) lädt MindSift beim ersten Start automatisch in ./whisper. - # RAM: large-v3-turbo ca. 2 GB, small ca. 1 GB. - whisper: - image: ghcr.io/speaches-ai/speaches:0.8.3-cpu - container_name: mindsift-whisper - restart: unless-stopped - profiles: ["whisper"] - volumes: - - ./whisper:/home/ubuntu/.cache/huggingface/hub - environment: - - WHISPER__COMPUTE_TYPE=int8 # schneller und sparsamer auf der CPU, kaum Qualitätsverlust - - STT_MODEL_TTL=-1 # Modell im Speicher halten (sonst nach 5 Min. entladen, nächste Erkennung lädt neu) - - ENABLE_UI=false # keine Weboberfläche von speaches - - LOG_LEVEL=info - # Kein Port nach außen: nur MindSift spricht im Docker-Netz mit dem Dienst. + # Optional: eigene Spracherkennung (Whisper). Zum Einschalten: + # 1. die Rauten vor dem Block "whisper" unten entfernen + # 2. in .env setzen: STT_URL=http://whisper:8000 + # 3. mkdir -p whisper && sudo chown 1000:1000 whisper (der Container läuft als UID 1000) + # 4. docker compose up -d + # Das Modell lädt MindSift beim ersten Start selbst nach ./whisper (large-v3-turbo ca. 1,6 GB). + # RAM: large-v3-turbo ca. 2 GB, small ca. 1 GB. Kein Port nach außen nötig. + # + # whisper: + # image: ghcr.io/speaches-ai/speaches:0.8.3-cpu + # container_name: mindsift-whisper + # restart: unless-stopped + # volumes: + # - ./whisper:/home/ubuntu/.cache/huggingface/hub + # environment: + # - WHISPER__COMPUTE_TYPE=int8 # schneller auf der CPU, kaum Qualitätsverlust + # - STT_MODEL_TTL=-1 # Modell im Speicher halten statt nach 5 Min. zu entladen + # - ENABLE_UI=false # ohne die Weboberfläche von speaches + # - LOG_LEVEL=info