Files
linkvault/README.md
Erik Thiele 39058d09e2 Fix update instructions: set GIT_TOKEN before curl call
The example was missing "export GIT_TOKEN=...", causing an empty
Authorization header when copy-pasted as-is.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-19 20:39:45 +02:00

182 lines
7.0 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# LinkVault
KI-gestützte Link-Sammlung: Links einfügen → automatisch laden, **zusammenfassen**,
in **Kategorien / Hersteller** einsortieren und schnell **wiederfinden**.
## Funktionen
- 🔗 **Link hinzufügen** Seite wird geladen und der Textinhalt extrahiert.
- 🤖 **Automatische KI-Analyse** (OpenAI) Titel, Zusammenfassung, Kategorie,
Hersteller/Quelle und Tags werden erzeugt. Bestehende Kategorien werden
wiederverwendet, damit die Sammlung konsistent bleibt.
- 🗂️ **Filtern** nach Kategorie und Hersteller über die Seitenleiste.
- 🔍 **Suche** klassische Textsuche und optionale **semantische KI-Suche**
(findet auch sinnverwandte Treffer via Embeddings).
- 👥 **Mehrbenutzer** Registrierung/Login, jeder Nutzer sieht nur seine Links.
## Technik
- **Backend:** FastAPI (Python)
- **Frontend:** HTML + HTMX (kein Node.js nötig)
- **Datenbank:** SQLite (Standard, konfigurierbar über `DATABASE_URL`)
- **KI:** OpenAI (`gpt-4o-mini` + `text-embedding-3-small`, konfigurierbar)
## Schnellstart
```bash
./run.sh
```
Das Skript legt eine virtuelle Umgebung an, installiert die Abhängigkeiten,
erstellt bei Bedarf eine `.env` und startet den Server auf
http://127.0.0.1:8000.
Danach in `.env` den `OPENAI_API_KEY` eintragen und den Server neu starten.
> Ohne API-Key läuft die App trotzdem Links werden dann nur ohne KI-Analyse
> gespeichert (Kategorie „Sonstiges", keine Zusammenfassung/semantische Suche).
### Manuell
```bash
python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
cp .env.example .env # OPENAI_API_KEY eintragen
uvicorn app.main:app --reload --port 8000
```
## Projektstruktur
```
app/
main.py FastAPI-App, Routen, Auth-Sessions
config.py Konfiguration aus .env
database.py SQLAlchemy Engine/Session
models.py User- und Link-Modelle
security.py Passwort-Hashing (bcrypt)
scraper.py Seiteninhalt laden & extrahieren
ai.py OpenAI: Kategorisierung, Zusammenfassung, Embeddings
search.py Semantische Suche (Kosinus-Ähnlichkeit)
templates/ Jinja2 + HTMX Oberfläche
```
## Proxmox
Für den Betrieb in einem Proxmox-VE-LXC-Container gibt es ein Helper-Script
(`scripts/proxmox/install-linkvault.sh`). Es legt automatisch einen
Debian-12-Container an und richtet LinkVault darin als systemd-Service ein.
### Installation
Das Repo ist **privat** für den Download des Scripts und für den `git clone`
innerhalb des Containers wird ein Gitea Access Token benötigt:
1. In Gitea: **Einstellungen → Anwendungen → Neuen Token erzeugen** (Scope
`read:repository` genügt).
2. Token als Umgebungsvariable `GIT_TOKEN` bereitstellen.
Auf dem **Proxmox-Host** (als root) ausführen:
```bash
export GIT_TOKEN=<dein-token>
bash <(curl -fsSL -H "Authorization: token ${GIT_TOKEN}" \
https://gitea.teamthiele.de/ethiele/linkvault/raw/branch/main/scripts/proxmox/install-linkvault.sh)
```
`GIT_TOKEN` wird automatisch an das Script weitergereicht und auch beim
`git clone` innerhalb des LXC-Containers verwendet.
Alternativ, falls das Repo bereits lokal ausgecheckt ist:
```bash
bash scripts/proxmox/install-linkvault.sh
```
Das Script:
1. lädt bei Bedarf das Debian-12-LXC-Template herunter,
2. erstellt einen unprivilegierten LXC-Container,
3. installiert darin Python, klont das Repo nach `/opt/linkvault`,
4. legt ein venv an und installiert die Abhängigkeiten,
5. erzeugt eine `.env` mit zufälligem `SECRET_KEY`,
6. richtet LinkVault als systemd-Service (`linkvault.service`) ein und startet ihn.
Am Ende gibt das Script die URL des Containers sowie das generierte
root-Passwort aus.
### Konfiguration
Alle Einstellungen lassen sich per Umgebungsvariable vor dem Aufruf setzen
(Defaults siehe Kopf des Scripts):
| Variable | Bedeutung | Default |
|-------------------|-----------------------------------------|---------------------------------|
| `CTID` | Container-ID | nächste freie ID |
| `CT_HOSTNAME` | Hostname des Containers | `linkvault` |
| `CT_DISK_GB` | Größe der Root-Disk in GB | `8` |
| `CT_MEMORY_MB` | RAM in MB | `1024` |
| `CT_SWAP_MB` | Swap in MB | `512` |
| `CT_CORES` | CPU-Kerne | `2` |
| `CT_BRIDGE` | Netzwerk-Bridge | `vmbr0` |
| `CT_IP` | Statische IP (`192.168.1.50/24`) oder `dhcp` | `dhcp` |
| `CT_GW` | Gateway (nur bei statischer IP nötig) | |
| `CT_STORAGE` | Storage für die Root-Disk | `local-lvm` |
| `TEMPLATE_STORAGE`| Storage für das LXC-Template | `local` |
| `CT_PASSWORD` | root-Passwort des Containers | zufällig generiert |
| `REPO_URL` | Git-Repo, das geklont wird | `.../ethiele/linkvault.git` |
| `APP_PORT` | Port, auf dem uvicorn lauscht | `8000` |
| `GIT_TOKEN` | Gitea Access Token (privates Repo) | |
Beispiel mit statischer IP und fester Container-ID:
```bash
export GIT_TOKEN=<dein-token>
CTID=150 CT_HOSTNAME=linkvault CT_IP=192.168.1.50/24 CT_GW=192.168.1.1 \
bash <(curl -fsSL -H "Authorization: token ${GIT_TOKEN}" \
https://gitea.teamthiele.de/ethiele/linkvault/raw/branch/main/scripts/proxmox/install-linkvault.sh)
```
### Nach der Installation
In `/opt/linkvault/.env` **innerhalb des Containers** den `OPENAI_API_KEY`
eintragen (siehe [Schnellstart](#schnellstart) für weitere `.env`-Optionen),
danach den Dienst neu starten:
```bash
pct exec <CTID> -- systemctl restart linkvault
```
Nützliche Befehle:
```bash
pct exec <CTID> -- systemctl status linkvault # Status prüfen
pct exec <CTID> -- journalctl -u linkvault -f # Logs verfolgen
```
### Updaten
Wenn sich im Git-Repo etwas geändert hat, den Container mit
`scripts/proxmox/update-linkvault.sh` auf den neuesten Stand bringen. Das
Script zieht per `git pull`, aktualisiert die Python-Abhängigkeiten und
startet den systemd-Service neu. Auf dem **Proxmox-Host** ausführen:
```bash
export GIT_TOKEN=<dein-token>
CTID=113 bash <(curl -fsSL -H "Authorization: token ${GIT_TOKEN}" \
https://gitea.teamthiele.de/ethiele/linkvault/raw/branch/main/scripts/proxmox/update-linkvault.sh)
```
(`GIT_TOKEN` nur nötig, falls das Repo privat ist siehe oben.)
Alternativ, falls das Repo bereits lokal ausgecheckt ist:
```bash
CTID=113 bash scripts/proxmox/update-linkvault.sh
```
## Hinweise für den Produktivbetrieb
- Einen zufälligen `SECRET_KEY` in `.env` setzen.
- Hinter einem HTTPS-Reverse-Proxy betreiben (Session-Cookies).
- Für mehr Last statt SQLite z.B. PostgreSQL via `DATABASE_URL` verwenden.