Docs: close the gaps an audit turned up
Audited README, BEDIENUNGSANLEITUNG and CLAUDE.md against what the repo and the running stack actually do. Findings, all fixed: - CLAUDE.md claimed the repo holds "only deployment config (docker-compose.yml, .env, .gitignore)". It has not been that for a while: services/ is our own source (TTS/STT servers + systemd units), scripts/ is tooling, and prompts/podcast/ + config/content_core.yaml are overlays bind-mounted over the image. Those overlays are the fragile part, so the section now says so and points at smoke_test.sh. - CLAUDE.md still described the image as a moving tag and argued against patching app code "because it would rot against pull_policy: always" — both obsolete since the digest pin. - README listed neither yt-dlp (needed by add_video_source.py) nor smoke_test.sh in the verification step, and section 2.3 still told you to `docker compose pull` as if the tag moved. - BEDIENUNGSANLEITUNG had nothing at all about updates — the very thing a user has to do periodically. New section 8 covers check_updates / update_stack / smoke_test and, importantly, why updating is not automatic (DB migration is one-way without a backup; the local adaptations can break silently without crashing). - Renumbered the ad-hoc "3a. Updates" in README into a real section 4, and the BEDIENUNGSANLEITUNG sections after the new 8 accordingly. Verified mechanically: every scripts//services//config//prompts/ path named in the docs exists, and all internal and cross-document anchors resolve (0 dead links — one was already broken before this change: README pointed at BEDIENUNGSANLEITUNG.md#stimmklonung instead of #5-stimmklonung). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
4805fe75ed
commit
09c6d910a7
3 changed files with 82 additions and 16 deletions
|
|
@ -15,9 +15,10 @@ siehe [`CLAUDE.md`](CLAUDE.md).
|
||||||
5. [Stimmklonung](#5-stimmklonung)
|
5. [Stimmklonung](#5-stimmklonung)
|
||||||
6. [Modelle und Provider verwalten](#6-modelle-und-provider-verwalten)
|
6. [Modelle und Provider verwalten](#6-modelle-und-provider-verwalten)
|
||||||
7. [Dienste starten/stoppen](#7-dienste-startenstoppen)
|
7. [Dienste starten/stoppen](#7-dienste-startenstoppen)
|
||||||
8. [Suche über Chunks (Search/Ask)](#8-suche-über-chunks-searchask)
|
8. [Updates einspielen](#8-updates-einspielen)
|
||||||
9. [Die API in eigenen Programmen nutzen](#9-die-api-in-eigenen-programmen-nutzen)
|
9. [Suche über Chunks (Search/Ask)](#9-suche-über-chunks-searchask)
|
||||||
10. [Troubleshooting](#10-troubleshooting)
|
10. [Die API in eigenen Programmen nutzen](#10-die-api-in-eigenen-programmen-nutzen)
|
||||||
|
11. [Troubleshooting](#11-troubleshooting)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
@ -256,7 +257,54 @@ ollama ps # aktuell geladene Modelle + GPU/CPU-Verteilung
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 8. Suche über Chunks (Search/Ask)
|
## 8. Updates einspielen
|
||||||
|
|
||||||
|
Open Notebook läuft hier auf einer **festgenagelten Version** (Digest-Pin in
|
||||||
|
`docker-compose.yml`). Weder ein Start noch ein Reboot tauscht die Anwendung unbemerkt aus — Sie
|
||||||
|
bekommen immer genau den Stand, der zuletzt geprüft wurde.
|
||||||
|
|
||||||
|
**Beim Sitzungsstart** (ändert nichts, dauert Sekunden):
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./scripts/check_updates.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
Ausgabe entweder „Du laeufst auf dem aktuellen Release. Nichts zu tun." oder ein Hinweis auf ein
|
||||||
|
neues Image.
|
||||||
|
|
||||||
|
**Update einspielen:**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./scripts/update_stack.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
Das Skript sichert zuerst Datenbank und Notebook-Daten nach `backups/<Zeitstempel>/`, stellt dann
|
||||||
|
auf das neue Image um, startet den Stack und fährt einen **Rauchtest** (API, Sprachausgabe,
|
||||||
|
Spracherkennung, YouTube-Import, alle lokalen Anpassungen). Schlägt der fehl, wird **automatisch
|
||||||
|
zurückgerollt** — Daten und Konfiguration landen wieder auf dem alten Stand.
|
||||||
|
|
||||||
|
Läuft alles, committen Sie den neuen Stand:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git add docker-compose.yml && git commit -m "Update auf <Version>"
|
||||||
|
```
|
||||||
|
|
||||||
|
**Warum nicht einfach immer die neueste Version?** Ein Update verändert das Datenbankschema, und
|
||||||
|
eine ältere Version kann eine bereits migrierte Datenbank in der Regel nicht mehr lesen — ohne
|
||||||
|
Sicherung wäre ein misslungenes Update also eine Einbahnstraße. Außerdem hängen die Anpassungen
|
||||||
|
dieser Installation (Podcast-Vorlagen, YouTube-Sprachen, TTS-Einstellungen) an Interna der
|
||||||
|
Anwendung und können durch ein Update **still** kaputtgehen, ohne dass etwas abstürzt. Genau
|
||||||
|
deshalb der Rauchtest.
|
||||||
|
|
||||||
|
Ihn können Sie auch jederzeit einzeln laufen lassen, etwa wenn sich etwas seltsam verhält:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./scripts/smoke_test.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 9. Suche über Chunks (Search/Ask)
|
||||||
|
|
||||||
Jedes Dokument wird beim Hochladen automatisch in feste, überlappende Textabschnitte
|
Jedes Dokument wird beim Hochladen automatisch in feste, überlappende Textabschnitte
|
||||||
("Chunks", ~400 Tokens) zerlegt und eingebettet — **nicht** kapitelweise, sondern rein
|
("Chunks", ~400 Tokens) zerlegt und eingebettet — **nicht** kapitelweise, sondern rein
|
||||||
|
|
@ -300,7 +348,7 @@ weil nur die relevanten Chunks statt des ganzen Dokuments verarbeitet werden.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 9. Die API in eigenen Programmen nutzen
|
## 10. Die API in eigenen Programmen nutzen
|
||||||
|
|
||||||
Die REST-API ist eine ganz normale JSON-über-HTTP-API **ohne Authentifizierung** — kein API-Key
|
Die REST-API ist eine ganz normale JSON-über-HTTP-API **ohne Authentifizierung** — kein API-Key
|
||||||
nötig, da nur `127.0.0.1` gebunden (jeder lokale Prozess auf diesem Rechner hat Zugriff, aber
|
nötig, da nur `127.0.0.1` gebunden (jeder lokale Prozess auf diesem Rechner hat Zugriff, aber
|
||||||
|
|
@ -361,7 +409,7 @@ Spezifisches nötig, kein SDK erforderlich.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 10. Troubleshooting
|
## 11. Troubleshooting
|
||||||
|
|
||||||
### „Chat gibt keine Antwort" (leere Antwort, kein Fehler)
|
### „Chat gibt keine Antwort" (leere Antwort, kein Fehler)
|
||||||
|
|
||||||
|
|
|
||||||
15
CLAUDE.md
15
CLAUDE.md
|
|
@ -4,7 +4,13 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co
|
||||||
|
|
||||||
## What this repo is
|
## What this repo is
|
||||||
|
|
||||||
This is a local Docker Compose deployment of [Open Notebook](https://github.com/lfnovo/open-notebook) (upstream image `lfnovo/open_notebook`), not a clone of its source. There is no application source code here — only deployment config (`docker-compose.yml`, `.env`, `.gitignore`). Application bugs/features belong upstream; this repo only concerns itself with how the stack is run locally.
|
This is a local Docker Compose deployment of [Open Notebook](https://github.com/lfnovo/open-notebook) (upstream image `lfnovo/open_notebook`), not a clone of its source. The application's own code is **not** here and its bugs/features belong upstream — this repo only concerns itself with how the stack is run locally.
|
||||||
|
|
||||||
|
What *is* here, beyond `docker-compose.yml`/`.env`:
|
||||||
|
|
||||||
|
- `services/` — our own source: the TTS/STT wrapper servers (Open Notebook has no local TTS/STT provider) plus their systemd units.
|
||||||
|
- `scripts/` — setup, maintenance and update tooling (see Commands below).
|
||||||
|
- `prompts/podcast/`, `config/content_core.yaml` — **overlays** bind-mounted over files inside the image, to fix upstream behaviour we can't configure otherwise (podcast language/reliability, YouTube caption languages). These are the fragile part: they can silently rot when the image is updated, which is what `scripts/smoke_test.sh` exists to catch.
|
||||||
|
|
||||||
## Commands
|
## Commands
|
||||||
|
|
||||||
|
|
@ -71,7 +77,7 @@ check.
|
||||||
Two services, defined in `docker-compose.yml`:
|
Two services, defined in `docker-compose.yml`:
|
||||||
|
|
||||||
- **surrealdb** (`surrealdb/surrealdb:v2`) — the database, RocksDB-backed, bound to `127.0.0.1:8000` only (local debugging access, e.g. `surreal sql`). Credentials come from `SURREAL_USER`/`SURREAL_PASSWORD` (default `root`/`root` if unset in `.env`) and are shared with the `open_notebook` service so they stay in sync.
|
- **surrealdb** (`surrealdb/surrealdb:v2`) — the database, RocksDB-backed, bound to `127.0.0.1:8000` only (local debugging access, e.g. `surreal sql`). Credentials come from `SURREAL_USER`/`SURREAL_PASSWORD` (default `root`/`root` if unset in `.env`) and are shared with the `open_notebook` service so they stay in sync.
|
||||||
- **open_notebook** (`lfnovo/open_notebook:v1-latest`) — bundles the web UI (port 8502) and REST API (port 5055) in one image, both bound to `127.0.0.1` only. Connects to `surrealdb` over the internal compose network (`ws://surrealdb:8000/rpc`).
|
- **open_notebook** (`lfnovo/open_notebook:v1-latest`, digest-pinned — see *Image versioning*) — bundles the web UI (port 8502) and REST API (port 5055) in one image, both bound to `127.0.0.1` only. Connects to `surrealdb` over the internal compose network (`ws://surrealdb:8000/rpc`).
|
||||||
|
|
||||||
Data persists in `./surreal_data` and `./notebook_data` (bind mounts, gitignored).
|
Data persists in `./surreal_data` and `./notebook_data` (bind mounts, gitignored).
|
||||||
|
|
||||||
|
|
@ -130,8 +136,9 @@ dialogue segment), `outline.json` and `transcript.json`, is never touched, and n
|
||||||
Failed and `/retry`-replaced runs leak a directory too (the retry writes a *new* episode row with a new
|
Failed and `/retry`-replaced runs leak a directory too (the retry writes a *new* episode row with a new
|
||||||
uuid dir; the old one loses its DB entry and just stays). Upstream this would be roughly
|
uuid dir; the old one loses its DB entry and just stays). Upstream this would be roughly
|
||||||
`shutil.rmtree(audio_path.parent.parent)` in that handler. We deliberately do **not** patch it here by
|
`shutil.rmtree(audio_path.parent.parent)` in that handler. We deliberately do **not** patch it here by
|
||||||
bind-mounting a modified router — that would fork app logic into a deployment repo and silently rot
|
bind-mounting a modified router — that would fork app logic into a deployment repo and rot against
|
||||||
against `pull_policy: always`. Instead: `scripts/prune_podcast_data.py` (dry-run by default, `--yes` to
|
image updates (the same trap the existing overlays already carry). Instead:
|
||||||
|
`scripts/prune_podcast_data.py` (dry-run by default, `--yes` to
|
||||||
apply) reconciles the episode list from the API against the directories on disk and removes orphans plus
|
apply) reconciles the episode list from the API against the directories on disk and removes orphans plus
|
||||||
the `clips/` of completed episodes. Two guards matter — it aborts if any job is `running`/`pending`
|
the `clips/` of completed episodes. Two guards matter — it aborts if any job is `running`/`pending`
|
||||||
(a running job has no `audio_file` yet, so its directory is indistinguishable from an orphan) and it
|
(a running job has no `audio_file` yet, so its directory is indistinguishable from an orphan) and it
|
||||||
|
|
|
||||||
23
README.md
23
README.md
|
|
@ -49,6 +49,8 @@ Der `open_notebook`-Container erreicht Ollama und die TTS/STT-Wrapper über
|
||||||
in Schritt 2)
|
in Schritt 2)
|
||||||
- **`ufw`** (falls als Firewall aktiv) — Standardrichtlinie „deny incoming“ wird vorausgesetzt
|
- **`ufw`** (falls als Firewall aktiv) — Standardrichtlinie „deny incoming“ wird vorausgesetzt
|
||||||
- **`openssl`**, **`ffmpeg`**, **`curl`**, **`python3`**
|
- **`openssl`**, **`ffmpeg`**, **`curl`**, **`python3`**
|
||||||
|
- **`yt-dlp`** — nur für `scripts/add_video_source.py` (Videos ohne Untertitel); der übrige Stack
|
||||||
|
läuft auch ohne
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
@ -80,11 +82,14 @@ chmod 600 .env
|
||||||
### 2.3 Container starten
|
### 2.3 Container starten
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
docker compose pull
|
|
||||||
docker compose up -d
|
docker compose up -d
|
||||||
docker compose ps # beide Container sollten "Up" sein
|
docker compose ps # beide Container sollten "Up" sein
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Die Images sind in `docker-compose.yml` auf einen **Digest gepinnt** (`pull_policy: missing`) —
|
||||||
|
`up -d` lädt sie beim ersten Mal und danach nie wieder unbemerkt eine andere Version. Aktualisiert
|
||||||
|
wird bewusst, siehe [Abschnitt 4](#4-updates).
|
||||||
|
|
||||||
Web-UI: `http://localhost:8502` · REST-API: `http://localhost:5055` (beide nur `127.0.0.1`).
|
Web-UI: `http://localhost:8502` · REST-API: `http://localhost:5055` (beide nur `127.0.0.1`).
|
||||||
|
|
||||||
### 2.4 Firewall öffnen für TTS/STT
|
### 2.4 Firewall öffnen für TTS/STT
|
||||||
|
|
@ -123,7 +128,7 @@ journalctl --user -u open-notebook-tts -f
|
||||||
|
|
||||||
Für Stimmklonung mindestens eine Referenz-WAV in `services/voices/default.wav` ablegen (z. B.
|
Für Stimmklonung mindestens eine Referenz-WAV in `services/voices/default.wav` ablegen (z. B.
|
||||||
Symlink auf eine eigene Sprachaufnahme, 10–30s, WAV) — siehe
|
Symlink auf eine eigene Sprachaufnahme, 10–30s, WAV) — siehe
|
||||||
[`BEDIENUNGSANLEITUNG.md`](BEDIENUNGSANLEITUNG.md#stimmklonung).
|
[`BEDIENUNGSANLEITUNG.md`](BEDIENUNGSANLEITUNG.md#5-stimmklonung).
|
||||||
|
|
||||||
### 2.6 KI-Provider und Modelle registrieren
|
### 2.6 KI-Provider und Modelle registrieren
|
||||||
|
|
||||||
|
|
@ -161,6 +166,12 @@ curl -s http://127.0.0.1:8901/health # Chatterbox TTS
|
||||||
curl -s http://127.0.0.1:8902/health # faster-whisper STT
|
curl -s http://127.0.0.1:8902/health # faster-whisper STT
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Gründlicher — prüft API, TTS, STT, YouTube-Extraktion und alle lokalen Anpassungen auf einmal:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./scripts/smoke_test.sh
|
||||||
|
```
|
||||||
|
|
||||||
UI öffnen (`http://localhost:8502`), ein Notebook anlegen, eine Quelle hinzufügen und chatten —
|
UI öffnen (`http://localhost:8502`), ein Notebook anlegen, eine Quelle hinzufügen und chatten —
|
||||||
siehe [`BEDIENUNGSANLEITUNG.md`](BEDIENUNGSANLEITUNG.md) für die weitere Bedienung.
|
siehe [`BEDIENUNGSANLEITUNG.md`](BEDIENUNGSANLEITUNG.md) für die weitere Bedienung.
|
||||||
|
|
||||||
|
|
@ -194,7 +205,7 @@ Ersteinrichtung bzw. nach Änderungen an den Unit-Dateien nötig.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 3a. Updates
|
## 4. Updates
|
||||||
|
|
||||||
Die Images sind **auf einen Digest gepinnt** — es läuft immer genau der Stand, der im Repo steht.
|
Die Images sind **auf einen Digest gepinnt** — es läuft immer genau der Stand, der im Repo steht.
|
||||||
Weder ein `docker compose up -d` noch ein Reboot tauscht die Anwendung unbemerkt aus.
|
Weder ein `docker compose up -d` noch ein Reboot tauscht die Anwendung unbemerkt aus.
|
||||||
|
|
@ -223,7 +234,7 @@ typischerweise Wochen voraus, aber unveröffentlicht. Wer den will, müsste selb
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 4. Verzeichnisstruktur
|
## 5. Verzeichnisstruktur
|
||||||
|
|
||||||
```
|
```
|
||||||
open-notebook/
|
open-notebook/
|
||||||
|
|
@ -256,7 +267,7 @@ open-notebook/
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 5. Bekannte Stolpersteine
|
## 6. Bekannte Stolpersteine
|
||||||
|
|
||||||
Kurzreferenz — Details jeweils in [`CLAUDE.md`](CLAUDE.md):
|
Kurzreferenz — Details jeweils in [`CLAUDE.md`](CLAUDE.md):
|
||||||
|
|
||||||
|
|
@ -297,4 +308,4 @@ Kurzreferenz — Details jeweils in [`CLAUDE.md`](CLAUDE.md):
|
||||||
Vorlagen enthalten zusätzlich `/no_think`, damit `qwen3.5:27b` bei langem Quellinhalt nicht
|
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
|
durch überlange Reasoning-Blöcke ungültiges JSON liefert. Änderst du die Vorlagen, danach
|
||||||
`docker compose up -d --force-recreate open_notebook`. Details:
|
`docker compose up -d --force-recreate open_notebook`. Details:
|
||||||
[`BEDIENUNGSANLEITUNG.md`](BEDIENUNGSANLEITUNG.md#10-troubleshooting) und [`CLAUDE.md`](CLAUDE.md).
|
[`BEDIENUNGSANLEITUNG.md`](BEDIENUNGSANLEITUNG.md#11-troubleshooting) und [`CLAUDE.md`](CLAUDE.md).
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue