llama.cpp-Server-Instanzen, die als Docker-Container laufen —
inklusive einer SSRF-gehärteten Eingabeschicht für System- und User-Prompts aus
Text, Datei oder Remote-URL.
- Python 94.4%
- Shell 5.6%
Steuert einen llama.cpp-Server als Docker-Container: --start/--check/--stop/
--change/--chat, INI-Konfiguration (builtin defaults -> [default] ->
[model.<profile>] -> CLI), SSRF-gehärtete Prompt-Eingabe (Datei/HTTPS-URL),
File-Locking für --start/--change und ein OpenAI-kompatibler HTTP-Layer.
Enthält u. a.:
- Env-Var-Expansion in hf_home (hf_home = ${HF_HOME})
- konfigurierbares Chat-Antwortbudget (max_tokens/chat_temperature,
CLI: --max-tokens/--chat-temp); temperature defer an Server-Default
- DNS-Pinning gegen DNS-Rebinding bei URL-Quellen
- dry-run als nebenwirkungsfreie Vorschau (kein Lock/Removal/Modell-Check)
- 98 Tests (pytest)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
||
|---|---|---|
| docs | ||
| man | ||
| src/llamacppctl | ||
| tests | ||
| .gitignore | ||
| build_archive.py | ||
| llama.cpp.config | ||
| llama.cpp.config.example | ||
| pyproject.toml | ||
| README.md | ||
| requirements-dev.txt | ||
| requirements.txt | ||
llamacppctl
Ein einziges, sicherheitsgehärtetes CLI-Werkzeug zum Starten, Prüfen, Stoppen und
Wechseln von llama.cpp-Server-Instanzen, die als Docker-Container laufen —
inklusive einer SSRF-gehärteten Eingabeschicht für System- und User-Prompts aus
Text, Datei oder Remote-URL.
llamacppctl ersetzt eine Sammlung einzelner Shell-Skripte
(start-llm-server.sh, status-llm-server.sh, switch-llm.sh, …) durch ein
einziges Python-Paket mit konsistenter Konfiguration, Locking und
Fehlerbehandlung.
Installation
tar xzf llamacppctl-installable.tar.gz
cd llamacppctl
python3 -m venv .venv
source .venv/bin/activate
pip install .
Danach steht der Befehl llamacppctl innerhalb der aktivierten virtuellen
Umgebung zur Verfügung. Für eine systemweite Installation (ohne venv):
pip install --user .
Voraussetzungen auf dem Zielsystem:
- Python >= 3.10
- Docker (CLI + laufender Daemon), für
--start/--check/--stop/--change` - Netzwerkzugriff auf den Container-Host-Port für
--chat/--check`
--print-effective-config und --dry-run benötigen keinen laufenden Docker-Daemon
für die reine Konfigurationsprüfung; --start/--check/--stop/--change` erfordern
einen erreichbaren Docker-Daemon.
Konfiguration
Kopiere llama.cpp.config.example nach llama.cpp.config und passe es an:
cp llama.cpp.config.example llama.cpp.config
Abschnittstypen:
[default]— globale Defaults, überschreiben die eingebauten Fallback-Werte[model.<name>]— ein Modell-Profil, ausgewählt über--profile <name>[prompt.<name>]— ein System-Prompt-Profil, ausgewählt über--system-prompt-profile <name>(liefert nur einen Fallback-Systemprompt; ein explizites-s/--system-file/--system-urlgewinnt immer)
container_name ist Pflicht und muss für jedes Profil, das parallel
laufen soll, eindeutig sein — er ist der einzige Identitätsanker für
Docker-Namensgebung, Locking (--start/--change) sowie
--stop/--check-Ziel.
hf_home unterstützt Environment-Variablen und ~, z. B. hf_home = ${HF_HOME}.
Das Chat-Antwortbudget ist ebenfalls konfigurierbar (wirkt auf --chat und die
Antwort nach --start, nicht auf den Container): max_tokens (Default 2048 —
für Reasoning-Modelle / lange Texte hochsetzen, sonst bricht die Antwort mitten
im „Denken" ab und content bleibt leer) und chat_temperature (leer =
Server-temp gilt). CLI-Overrides: --max-tokens, --chat-temp.
Auflösungsreihenfolge (niedrigste zu höchster Priorität):
- Eingebaute Defaults
[default]-Sektion[model.<profile>]-Sektion (falls--profilegesetzt)- CLI-Overrides (
--image,--host-port, …)
Verwendung
# Server starten
llamacppctl --start --config llama.cpp.config --profile qwen35
# Nur den geplanten docker-run-Befehl anzeigen, nichts ausführen
llamacppctl --start --config llama.cpp.config --profile qwen35 --dry-run
# Effektive Konfiguration als JSON ausgeben
llamacppctl --print-effective-config --config llama.cpp.config --profile qwen35 --start
# Status prüfen
llamacppctl --check --config llama.cpp.config --profile qwen35
# Server stoppen und Container entfernen
llamacppctl --stop --config llama.cpp.config --profile qwen35
# Modell wechseln (stop, neu konfigurieren, restart) unter Lock-Schutz
llamacppctl --change --config llama.cpp.config --profile deepseek
# Direkten Chat-Request an einen laufenden Server senden
llamacppctl --chat --config llama.cpp.config --profile qwen35 \
-s "Du antwortest kurz." -p "Was ist 2+2?"
# System-Prompt aus einer lokalen Datei, User-Prompt als Literal
llamacppctl --start --config llama.cpp.config --profile qwen35 \
--system-file ./prompts/coding.md -p "Refaktoriere diese Funktion."
# System-Prompt von einer HTTPS-URL (öffentliches, nicht-privates Ziel)
llamacppctl --chat --config llama.cpp.config --profile qwen35 \
--system-url https://example.com/prompts/system.txt -p "Hallo"
Vollständige Optionsliste: llamacppctl --help oder die Manpage
(man/llamacppctl.1, siehe unten).
Sicherheitsmodell (Kurzfassung)
Für Details siehe docs/SECURITY_AND_OPERATIONS.md.
- Alle Docker-Aufrufe laufen über
subprocess.run()mit Argumentlisten — niemals über Shell-Strings, somit keine Shell-Injection-Fläche. --system-file/--prompt-filelesen ausschließlich reguläre Dateien, Größenlimit (--max-input-bytes, Default 1 MiB), UTF-8-Text erzwungen, Symlinks standardmäßig abgelehnt, per--allow-symlinks` freischaltbar.--system-url/--prompt-urlsind standardmäßig HTTPS-only, blockieren IP-Literale, private/loopback/link-local/reserved Adressbereiche sowie die Cloud-Metadata-IP169.254.169.254, verbieten eingebettete Zugangsdaten in der URL, erlauben standardmäßig keine Redirects (jeder Hop wird bei Aktivierung erneut validiert), erzwingen eine Content-Type-Allowlist und ein hartes Größenlimit sowohl überContent-Length` als auch beim Streaming.container_nameist verpflichtend und muss pro parallel betriebenem Profil eindeutig sein, um Docker-Namenskollisionen und ungewollte Container-Übernahmen zu verhindern.--start/--change` nutzen echte Chat-Completions zum Readiness-Check (nicht nur einen offenen Port), um sicherzustellen, dass das Modell tatsächlich geladen und inferenzfähig ist.--changeverwendet eine exklusive, nicht-blockierende Dateisperre (/tmp/llamacppctl.<container_name>.lock), um parallele Änderungen am selben Container zu verhindern.
Entwicklung / Tests
pip install -e ".[dev]"
pytest -q
Die Test-Suite deckt die Prompt-Eingabeschicht (Datei- und URL-Quellen inkl.
SSRF-Abwehr mit gemockter DNS-Auflösung), die Konfigurationsauflösung, die
CLI-Validierung sowie Docker-/HTTP-Operationen (mit gemocktem subprocess
bzw. requests) ab.
Lizenz
MIT