Docker-Image, Compose-Demo mit ./data-Mount

Alle Laufzeitdateien (config, ACLs, keys, state, aa-cache, log) gehen über
den Mount ./data:/data, weil logDir und ACLs relativ zum CONFIG_PATH
aufgelöst werden. Ohne Keys startet der Router trotzdem, /health bleibt
bedienbar.
This commit is contained in:
2026-09-08 09:48:13 +02:00
parent 3c0a8ead85
commit 1f99b73161
5 changed files with 88 additions and 0 deletions
+14
View File
@@ -0,0 +1,14 @@
# Vorlage: cp .env.example .env — Compose liest .env automatisch ein.
# Quellen der Werte: OpenBao agents/jessie/litellm (OpenRouter, AA, Kira)
# und agents/jessie/llmrouter (admin_key).
# Upstream-Provider
OPENROUTER_API_KEY=
MISTRAL_API_KEY=
KIRA_REASONING_KEY=
KIRA_STT_KEY=
KIRA_TTS_KEY=
ARTIFICIALANALYSIS_API_KEY=
# Schützt GET /stats, GET /zuordnung, POST /auffrischen
ADMIN_KEY=
+3
View File
@@ -1,3 +1,6 @@
log/
dist/
node_modules/
data/*
!data/README.md
.env
+21
View File
@@ -0,0 +1,21 @@
# ./data — Laufzeitverzeichnis des Containers
Hier liegen alle Dateien, die der Router schreibt oder nachladen soll; der
Compose-Dienst mountet dieses Verzeichnis nach `/data`. Beim ersten Start:
```sh
cp config.json key-acls.json data/
cp .env.example .env # dann Werte eintragen
docker compose up -d
```
| Datei | Zweck |
|---|---|
| `config.json` | Konfiguration (Aliasse, Rollen, Profile) — vom Repo übernehmen und anpassen; wird per `LLMROUTER_CONFIG` gelesen |
| `key-acls.json` | Rechte je Client-Name — per `LLMROUTER_ACLS` gelesen |
| `keys.json` | Client-Token → Name, 0600 empfohlen; pflegen mit `KEYS_FILE=/data/keys.json bun run src/keys.ts add <name>` |
| `model-blocklist.json` | optional, von Hand gepflegte Sperrliste (nur mit `MODEL_BLOCKLIST=/data/model-blocklist.json` aktiv) |
| `log/`, `state.json`, `aa-cache.json` | schreibt der Router selbst (Log, Zuordnungs-State, AA-Index-Cache) |
`log/`, `state.json` und `aa-cache.json` werden nicht versioniert — der
`.gitignore` lässt außer dieser README alles hier weg.
+30
View File
@@ -0,0 +1,30 @@
services:
llmrouter:
image: git.42i.org/spine/llmrouter:latest
build:
context: .
dockerfile: docker/Dockerfile
ports:
- "4010:4010"
volumes:
# Caches und Einstellungen liegen alle unter ./data — siehe data/README.md
- ./data:/data
environment:
# Konfiguration, ACLs, Keys und Logs wandern komplett nach /data,
# weil logDir und ACLs relativ zum CONFIG_PATH aufgelöst werden.
LLMROUTER_CONFIG: /data/config.json
LLMROUTER_ACLS: /data/key-acls.json
KEYS_FILE: /data/keys.json
# Upstream-Keys kommen aus .env (Vorlage: .env.example). Leere Werte
# sind okay: der Router startet trotzdem, Auffrischen scheitert dann
# graceful und /health bleibt bedienbar.
OPENROUTER_API_KEY: ${OPENROUTER_API_KEY:-}
MISTRAL_API_KEY: ${MISTRAL_API_KEY:-}
KIRA_REASONING_KEY: ${KIRA_REASONING_KEY:-}
KIRA_STT_KEY: ${KIRA_STT_KEY:-}
KIRA_TTS_KEY: ${KIRA_TTS_KEY:-}
ARTIFICIALANALYSIS_API_KEY: ${ARTIFICIALANALYSIS_API_KEY:-}
ADMIN_KEY: ${ADMIN_KEY:-}
# Optional: eigene Sperrliste statt der Default unter $HOME
# MODEL_BLOCKLIST: /data/model-blocklist.json
restart: unless-stopped
+20
View File
@@ -0,0 +1,20 @@
# llmrouter — ein Image, keine Abhängigkeiten (package.json hat keine deps).
# oven/bun:1 ist Debian-basiert und bringt bun mit; der Router läuft darin
# direkt aus den Quellen (kein Build-Schritt nötig).
FROM oven/bun:1
WORKDIR /app
# Mitgelieferte Demo-Konfiguration: greift nur, wenn LLMROUTER_CONFIG nicht
# gesetzt ist (Compose überschreibt sie mit /data/config.json).
COPY package.json ./
COPY src ./src
COPY config.json key-acls.json ./
EXPOSE 4010
# /health braucht keine Keys; der Router lauscht auch ohne Secret-Umfeld.
HEALTHCHECK --interval=30s --timeout=5s --start-period=10s --retries=3 \
CMD bun -e 'const p = Number(process.env.PORT ?? 4010); const r = await fetch("http://127.0.0.1:" + p + "/health"); process.exit(r.ok ? 0 : 1)'
CMD ["bun", "src/server.ts"]