Add README.md, BEDIENUNGSANLEITUNG.md, and setup/start scripts
README.md gives the precise, reproducible install path (tested the two
scripts against the live instance - both idempotent, correctly detect
already-registered credentials/models). BEDIENUNGSANLEITUNG.md covers daily
usage: notebooks/sources, the three chat context modes (and why "nur
Erkenntnisse" needs a transformation run first), podcasts, voice cloning,
and troubleshooting for the issues actually hit during setup (num_ctx
truncation, embedding GPU contention, ufw).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-10 23:50:58 +02:00
|
|
|
|
# Open Notebook (lokales Deployment)
|
|
|
|
|
|
|
|
|
|
|
|
Selbst gehostetes [Open Notebook](https://github.com/lfnovo/open-notebook) per Docker Compose —
|
|
|
|
|
|
KI-gestützter Notiz-/Recherche-Assistent mit Chat, Quellenverwaltung und Podcast-Erstellung.
|
|
|
|
|
|
|
|
|
|
|
|
**Nur zwei KI-Provider:**
|
|
|
|
|
|
- **Ollama** (lokal, auf dem Host, GPU 1+2 — RTX 3090) für Chat, Embedding, Tools
|
|
|
|
|
|
- **OpenRouter** (Cloud, einziger externer Provider) als Alternative/Ergänzung
|
|
|
|
|
|
|
|
|
|
|
|
Text-to-Speech und Speech-to-Text laufen ebenfalls lokal: [Chatterbox TTS](https://github.com/resemble-ai/chatterbox)
|
|
|
|
|
|
(mit Stimmklonung) und [faster-whisper](https://github.com/SYSTRAN/faster-whisper), beide über
|
|
|
|
|
|
schlanke selbstgeschriebene OpenAI-kompatible HTTP-Wrapper in `services/`.
|
|
|
|
|
|
|
|
|
|
|
|
Ausführliche Bedienung (Chat-Modi, Podcasts, Stimmen, Troubleshooting): siehe
|
|
|
|
|
|
[`BEDIENUNGSANLEITUNG.md`](BEDIENUNGSANLEITUNG.md). Architektur- und Betriebsdetails für
|
|
|
|
|
|
Weiterentwicklung: siehe [`CLAUDE.md`](CLAUDE.md).
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## Architektur
|
|
|
|
|
|
|
|
|
|
|
|
| Komponente | Läuft wo | Zweck |
|
|
|
|
|
|
|---|---|---|
|
|
|
|
|
|
| `surrealdb` | Docker | Datenbank (nur `127.0.0.1:8000`) |
|
|
|
|
|
|
| `open_notebook` | Docker | Web-UI (`:8502`) + REST-API (`:5055`) |
|
|
|
|
|
|
| Ollama | Host (systemd) | Chat-/Embedding-Modelle, GPU 1+2 |
|
|
|
|
|
|
| `services/tts_server.py` | Host (Hintergrundprozess) | Chatterbox TTS, GPU 2, Port `8901` |
|
|
|
|
|
|
| `services/stt_server.py` | Host (Hintergrundprozess) | faster-whisper STT, GPU 2, Port `8902` |
|
|
|
|
|
|
|
|
|
|
|
|
Der `open_notebook`-Container erreicht Ollama und die TTS/STT-Wrapper über
|
|
|
|
|
|
`host.docker.internal` (Linux-Route via `extra_hosts: host-gateway`).
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 1. Voraussetzungen
|
|
|
|
|
|
|
|
|
|
|
|
- **Docker** + Docker Compose (Plugin), Daemon läuft
|
|
|
|
|
|
- **Ollama** installiert und als Dienst aktiv (`systemctl status ollama`), erreichbar auf `11434`
|
|
|
|
|
|
- Empfohlene systemd-Umgebung für Multi-GPU-Setups mit dedizierter Desktop-GPU:
|
|
|
|
|
|
`CUDA_VISIBLE_DEVICES=1,2` (GPU 0 ausschließen), `OLLAMA_KEEP_ALIVE=-1`,
|
|
|
|
|
|
`OLLAMA_CONTEXT_LENGTH=131072`
|
|
|
|
|
|
- Benötigte Modelle: `qwen3.5:27b`, `nomic-embed-text` (weitere optional, siehe
|
|
|
|
|
|
`scripts/setup_models.sh`) — mit `ollama pull <modell>` laden
|
|
|
|
|
|
- **Python-Umgebungen für TTS/STT** (bereits vorhandene Installationen dieses Systems):
|
|
|
|
|
|
- Conda-Env `chatterbox` mit [chatterbox-tts](https://github.com/resemble-ai/chatterbox)
|
|
|
|
|
|
(`~/miniforge3/envs/chatterbox`, siehe `~/chatterbox-tts-cli/`)
|
|
|
|
|
|
- System-Python mit `faster-whisper`, `fastapi`, `uvicorn`
|
|
|
|
|
|
- **OPENROUTER_API_KEY** als Umgebungsvariable im Environment verfügbar (für die Secret-Generierung
|
|
|
|
|
|
in Schritt 2)
|
|
|
|
|
|
- **`ufw`** (falls als Firewall aktiv) — Standardrichtlinie „deny incoming“ wird vorausgesetzt
|
|
|
|
|
|
- **`openssl`**, **`ffmpeg`**, **`curl`**, **`python3`**
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 2. Installation
|
|
|
|
|
|
|
|
|
|
|
|
### 2.1 Repository
|
|
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
|
cd ~/open-notebook # bzw. Zielverzeichnis
|
|
|
|
|
|
git status # falls schon vorhanden: prüfen statt neu klonen
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
### 2.2 Secrets erzeugen (`.env`)
|
|
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
|
ENC_KEY=$(openssl rand -base64 32)
|
|
|
|
|
|
DB_PASS=$(openssl rand -base64 24 | tr -d '/+=')
|
|
|
|
|
|
cat > .env <<EOF
|
|
|
|
|
|
OPEN_NOTEBOOK_ENCRYPTION_KEY=${ENC_KEY}
|
|
|
|
|
|
SURREAL_USER=root
|
|
|
|
|
|
SURREAL_PASSWORD=${DB_PASS}
|
|
|
|
|
|
OPENROUTER_API_KEY=${OPENROUTER_API_KEY}
|
|
|
|
|
|
EOF
|
|
|
|
|
|
chmod 600 .env
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
`.env` wird nicht committed (siehe `.gitignore`). `.env.example` ist das Template.
|
|
|
|
|
|
|
|
|
|
|
|
### 2.3 Container starten
|
|
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
|
docker compose pull
|
|
|
|
|
|
docker compose up -d
|
|
|
|
|
|
docker compose ps # beide Container sollten "Up" sein
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
Web-UI: `http://localhost:8502` · REST-API: `http://localhost:5055` (beide nur `127.0.0.1`).
|
|
|
|
|
|
|
|
|
|
|
|
### 2.4 Firewall öffnen für TTS/STT
|
|
|
|
|
|
|
|
|
|
|
|
Die TTS/STT-Wrapper laufen auf dem Host; der Docker-Container erreicht sie über die
|
|
|
|
|
|
Docker-Bridge, was bei aktiver `ufw`-Firewall (Standard: deny incoming) explizit erlaubt werden muss —
|
|
|
|
|
|
analog zur bestehenden Regel für Ollama (`11434/tcp`):
|
|
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
|
sudo ufw allow 8901/tcp comment 'open-notebook TTS (chatterbox)'
|
|
|
|
|
|
sudo ufw allow 8902/tcp comment 'open-notebook STT (faster-whisper)'
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
Ohne diesen Schritt bleiben TTS/STT vom Container aus unerreichbar (Timeout), obwohl sie lokal
|
|
|
|
|
|
laufen und funktionieren.
|
|
|
|
|
|
|
|
|
|
|
|
### 2.5 TTS/STT-Server starten
|
|
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
|
./scripts/start_services.sh
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
Startet `tts_server.py` und `stt_server.py` als Hintergrundprozesse auf GPU 2 (nicht GPU 0/1,
|
|
|
|
|
|
um Ollama und die Desktop-GPU nicht zu belasten). Nicht systemd-verwaltet — nach einem Reboot
|
|
|
|
|
|
erneut ausführen. Logs: `services/logs/`.
|
|
|
|
|
|
|
|
|
|
|
|
Für Stimmklonung mindestens eine Referenz-WAV in `services/voices/default.wav` ablegen (z. B.
|
|
|
|
|
|
Symlink auf eine eigene Sprachaufnahme, 10–30s, WAV) — siehe
|
|
|
|
|
|
[`BEDIENUNGSANLEITUNG.md`](BEDIENUNGSANLEITUNG.md#stimmklonung).
|
|
|
|
|
|
|
|
|
|
|
|
### 2.6 KI-Provider und Modelle registrieren
|
|
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
|
./scripts/setup_models.sh
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
Richtet automatisch ein:
|
|
|
|
|
|
- Ollama-Credential (Chat + Embedding) mit `num_ctx=98304` — **wichtig**, siehe Warnkasten unten
|
|
|
|
|
|
- Kuratierte Ollama-Modelle: `qwen3.5:27b` (Standard für Chat/Tools/großer Kontext),
|
|
|
|
|
|
`nomic-embed-text` (Standard-Embedding), `qwen3-coder-30b-128k` (optional für Code)
|
|
|
|
|
|
- OpenRouter-API-Key aus `.env`/Environment in die verschlüsselte Datenbank migriert
|
|
|
|
|
|
- Kuratierte OpenRouter-Modelle (Claude Sonnet 5, Qwen3-Max, Gemini 3.5 Flash)
|
|
|
|
|
|
- Lokale TTS/STT-Wrapper als `openai_compatible`-Credentials + Standardmodelle
|
|
|
|
|
|
|
|
|
|
|
|
> **Warum `num_ctx` explizit gesetzt werden muss:** Ohne diese Einstellung begrenzt die
|
|
|
|
|
|
> zugrunde liegende Bibliothek (`esperanto`) jede Ollama-Chat-Anfrage stillschweigend auf
|
|
|
|
|
|
> 8192 Tokens Kontext — unabhängig vom eigentlichen Modell-Limit. Größere Chat-Kontexte
|
|
|
|
|
|
> (z. B. ganze Bücher im „Volltext"-Modus) werden dann abgeschnitten, und weil `qwen3.5:27b`
|
|
|
|
|
|
> ein „denkendes" Modell ist, kommt dabei oft eine **leere Antwort statt eines Fehlers**
|
|
|
|
|
|
> heraus. `98304` ist der größte Wert, der auf dieser Hardware (RTX 3090, 24 GB) noch
|
|
|
|
|
|
> vollständig auf der GPU bleibt (`ollama ps` → `100% GPU`). Details:
|
|
|
|
|
|
> [`CLAUDE.md`](CLAUDE.md).
|
|
|
|
|
|
|
|
|
|
|
|
### 2.7 Verifikation
|
|
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
|
curl -s http://127.0.0.1:5055/api/models/providers | python3 -m json.tool
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
Erwartung: `"available": ["openrouter", "ollama"]`. TTS/STT-Gesundheit:
|
|
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
|
curl -s http://127.0.0.1:8901/health # Chatterbox TTS
|
|
|
|
|
|
curl -s http://127.0.0.1:8902/health # faster-whisper STT
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
UI öffnen (`http://localhost:8502`), ein Notebook anlegen, eine Quelle hinzufügen und chatten —
|
|
|
|
|
|
siehe [`BEDIENUNGSANLEITUNG.md`](BEDIENUNGSANLEITUNG.md) für die weitere Bedienung.
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 3. Alltägliche Befehle
|
|
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
|
docker compose up -d # starten
|
|
|
|
|
|
docker compose down # stoppen (Daten bleiben erhalten)
|
|
|
|
|
|
docker compose logs -f open_notebook # Logs verfolgen
|
|
|
|
|
|
docker compose ps # Status
|
|
|
|
|
|
./scripts/start_services.sh # TTS/STT (re-)starten, z.B. nach Reboot
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 4. Verzeichnisstruktur
|
|
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
|
open-notebook/
|
|
|
|
|
|
├── docker-compose.yml # SurrealDB + open_notebook
|
|
|
|
|
|
├── .env # Secrets (gitignored)
|
|
|
|
|
|
├── .env.example # Template
|
|
|
|
|
|
├── surreal_data/ # DB-Daten (gitignored)
|
|
|
|
|
|
├── notebook_data/ # Notebook-Dateien/Uploads (gitignored)
|
|
|
|
|
|
├── services/
|
|
|
|
|
|
│ ├── tts_server.py # Chatterbox-Wrapper (OpenAI-API-kompatibel)
|
|
|
|
|
|
│ ├── stt_server.py # faster-whisper-Wrapper
|
|
|
|
|
|
│ ├── voices/ # Referenz-WAVs fürs Voice-Cloning (gitignored)
|
|
|
|
|
|
│ └── logs/ # (gitignored)
|
|
|
|
|
|
├── scripts/
|
|
|
|
|
|
│ ├── setup_models.sh # Provider/Modelle einrichten (idempotent)
|
|
|
|
|
|
│ └── start_services.sh # TTS/STT starten
|
|
|
|
|
|
├── README.md # diese Datei
|
|
|
|
|
|
├── BEDIENUNGSANLEITUNG.md # ausführliche Bedienungsanleitung (Deutsch)
|
|
|
|
|
|
└── CLAUDE.md # technische Architektur-Doku für Weiterentwicklung
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 5. Bekannte Stolpersteine
|
|
|
|
|
|
|
|
|
|
|
|
Kurzreferenz — Details jeweils in [`CLAUDE.md`](CLAUDE.md):
|
|
|
|
|
|
|
|
|
|
|
|
- **Embedding-Modell muss klein sein.** `qwen3-embedding` (ein zweckentfremdetes 8B-LLM,
|
|
|
|
|
|
~13 GB geladen) konkurriert mit dem Chat-Modell um GPU-Speicher und fällt dann teilweise auf
|
|
|
|
|
|
die CPU zurück — einzelne Embeddings dauern dann 40+ Sekunden und reißen Timeouts.
|
|
|
|
|
|
`nomic-embed-text` (274 MB) ist der Standard hier.
|
|
|
|
|
|
- **`num_ctx` beim Ollama-Chat-Credential ist Pflicht** (siehe Warnkasten in 2.6) — sonst
|
|
|
|
|
|
leere Chat-Antworten bei größerem Kontext, ohne sichtbaren Fehler.
|
|
|
|
|
|
- **Neue Host-Ports brauchen eine `ufw`-Regel**, sonst kann der Container sie nicht erreichen
|
|
|
|
|
|
(Timeout, keine Fehlermeldung in Open Notebook selbst).
|
2026-07-11 02:30:05 +02:00
|
|
|
|
- **Podcast-Sprache** wird über das `language`-Feld des Episode-Profils gesteuert, aber nur
|
|
|
|
|
|
dank der gepatchten Prompt-Vorlagen unter `prompts/podcast/` (per Bind-Mount in
|
|
|
|
|
|
`docker-compose.yml` eingehängt) — die Original-Vorlagen im Image ignorieren `language`, was
|
|
|
|
|
|
englische Podcasts (von der deutsch-fixierten TTS mit Akzent vorgelesen) verursachte. Die
|
|
|
|
|
|
Vorlagen enthalten zusätzlich `/no_think`, damit `qwen3.5:27b` bei langem Quellinhalt nicht
|
|
|
|
|
|
durch überlange Reasoning-Blöcke ungültiges JSON liefert. Änderst du die Vorlagen, danach
|
|
|
|
|
|
`docker compose up -d --force-recreate open_notebook`. Details:
|
|
|
|
|
|
[`BEDIENUNGSANLEITUNG.md`](BEDIENUNGSANLEITUNG.md#10-troubleshooting) und [`CLAUDE.md`](CLAUDE.md).
|