Konfiguration¶
questlog läuft als ein Container mit einem Volume, aus dem Image ghcr.io/marceltov/questlog. Ein Server braucht zwei Dateien und keinen Checkout: compose.yaml, das das Image startet, und daneben eine .env-Datei mit allen Einstellungen, eine ausgefüllte Kopie von .env.example. Einstellungen sind Umgebungsvariablen: QUESTLOG_*, dazu die gemeinsamen PUBLIC_URL, DATA_DIR, PORT und TZ.
curl -fsSLO https://raw.githubusercontent.com/Marceltov/questlog/main/compose.yaml
curl -fsSL -o .env https://raw.githubusercontent.com/Marceltov/questlog/main/.env.example
chmod 600 .env # dann ausfüllen
docker compose up -d
Aktualisieren: docker compose pull && docker compose up -d. :main folgt dem main-Branch; ein Image-Watcher wie Watchtower kann das nach seinem Zeitplan erledigen.
Variablen¶
| Variable | Standard | Was sie tut |
|---|---|---|
PUBLIC_URL |
http://localhost:${PORT} außerhalb von Produktion; in Produktion Pflicht |
Die Adresse, unter der Spieler und Claude questlog erreichen. Der Issuer der Anmeldung und die MCP-Ressource (${PUBLIC_URL}/mcp) werden daraus gebildet. |
DATA_DIR |
/data |
Enthält questlog.sqlite (das Log), auth.sqlite (Anmeldung) und, falls erzeugt, secret. |
PORT |
3000 |
Der Port, auf dem der Server lauscht. /mcp liest die Schlüssel der Anmeldung auch von 127.0.0.1:${PORT}. |
TZ |
Europe/Berlin |
Die Zeitzone von „heute", dem Standardtag einer Spielsession. |
QUESTLOG_SECRET |
erzeugt in ${DATA_DIR}/secret |
Signiert Session-Cookies und verschlüsselt die Schlüssel zum Signieren von Tokens. Mindestens 32 Bytes (openssl rand -hex 32). Eine Änderung meldet alle ab. |
QUESTLOG_SIGNUP_ALLOW |
leer: niemand Neues | Wer Spieler werden darf: Adressen, @domain-Einträge oder *, durch Kommas getrennt. Bestehende Spieler melden sich weiter an. |
QUESTLOG_SMTP_URL |
nicht gesetzt: keine E-Mail-Codes | Ein SMTP-Server für Anmeldecodes, smtp:// oder smtps://user:password@host:port. |
QUESTLOG_SMTP_FROM |
(Pflicht mit SMTP) | Die Absenderadresse der Codes. |
QUESTLOG_OIDC_<NAME>_ISSUER |
nicht gesetzt | Die Issuer-URL eines OpenID-Connect-Anbieters. <NAME> wählst du (Buchstaben und Ziffern); ein Block pro Anbieter. |
QUESTLOG_OIDC_<NAME>_CLIENT_ID |
(Pflicht mit Issuer) | Die Client-ID, die questlog bei diesem Anbieter hat. |
QUESTLOG_OIDC_<NAME>_CLIENT_SECRET |
leer | Ihr Secret, für einen vertraulichen Client. |
QUESTLOG_OIDC_<NAME>_LABEL |
der Name | Der Text des Knopfs: „Weiter mit <LABEL>". |
QUESTLOG_ANTHROPIC_API_KEY |
nicht gesetzt: kein Chat | Ein Claude-API-Schlüssel: schaltet den Chat in der Web-App ein (ADR 0013). Die Nachrichten bezahlt, wer die Instanz betreibt. |
QUESTLOG_ANTHROPIC_MODEL |
claude-opus-5-5 |
Das Modell, das der Chat nutzt. |
QUESTLOG_CHAT_DAILY_LIMIT |
100 |
Wie viele Chat-Nachrichten ein Spieler am Tag senden darf. |
QUESTLOG_TRANSCRIBE_URL |
nicht gesetzt: nur Tippen | Ein Whisper-Server, um in den Chat zu sprechen, mit dem OpenAI-kompatiblen /v1/audio/transcriptions, etwa speaches. Ohne Schrägstrich am Ende. |
QUESTLOG_TRANSCRIBE_MODEL |
deepdml/faster-whisper-large-v3-turbo-ct2 |
Das Modell, das der Whisper-Server nutzt. |
QUESTLOG_LOG_LEVEL |
info |
error, warn, info, debug oder silent. |
Mindestens ein Weg zur Anmeldung ist nötig: SMTP für E-Mail-Codes, oder ein Anbieter.
OpenID-Connect-Anbieter¶
Registriere questlog beim Anbieter (authentik, Google, jeder OpenID-Connect-Anbieter) mit der Redirect-URI ${PUBLIC_URL}/api/auth/callback/<name>, wobei <name> <NAME> in Kleinbuchstaben ist. Für authentik:
QUESTLOG_OIDC_AUTHENTIK_ISSUER=https://authentik.example.com/application/o/questlog/
QUESTLOG_OIDC_AUTHENTIK_CLIENT_ID=...
QUESTLOG_OIDC_AUTHENTIK_CLIENT_SECRET=...
QUESTLOG_OIDC_AUTHENTIK_LABEL=authentik
Eine Anmeldung über einen Anbieter wird mit einem bestehenden Spieler gleicher Adresse nur verbunden, wenn der Anbieter die Adresse als bestätigt meldet (ADR 0006).
Lehnt ein Anbieter eine Anmeldung ab, zeigt die Anmeldeseite seinen Fehlercode, und questlogs Log hat eine Zeile dazu.
Der Chat in der Web-App¶
Mit QUESTLOG_ANTHROPIC_API_KEY hat jede Seite einen Knopf Frag Claude und jede Karte einen kleinen, der den Chat zu dieser Karte öffnet. Der Chat nutzt dieselben Werkzeuge wie Claude über MCP, als der angemeldete Spieler, sieht also nichts, was der Spieler nicht sehen könnte, und nichts, was er noch nicht gefunden hat (ADR 0013). Das Gespräch bleibt auf dem Gerät des Spielers.
Um hineinzusprechen, lass neben questlog einen Whisper-Server laufen und richte QUESTLOG_TRANSCRIBE_URL darauf. Die Aufnahme geht nur dorthin und wird nie gespeichert. Mit speaches im Compose-Netz:
whisper:
image: ghcr.io/speaches-ai/speaches:latest-cpu
restart: unless-stopped
environment:
WHISPER__COMPUTE_TYPE: int8
WHISPER__TTL: "-1"
volumes:
- whisper-models:/home/ubuntu/.cache/huggingface/hub
und QUESTLOG_TRANSCRIBE_URL=http://whisper:8000 in der .env. Die erste Umwandlung lädt das Modell herunter.
Daten und Backups¶
Sichere DATA_DIR. questlog.sqlite ist das Log; auth.sqlite enthält Konten, Sessions und die verbundenen Clients, also enthält eine Kopie des Logs allein keine Tokens (ADR 0004). Geht auth.sqlite verloren, sind alle abgemeldet und es ist verloren, wer wer ist: Behalte beide.
SQLite läuft im WAL-Modus: Neue Daten stehen eine Weile in questlog.sqlite-wal. Sichere den ganzen Ordner, oder kopiere mit sqlite3 questlog.sqlite ".backup kopie.sqlite"; die Hauptdatei allein kann fast leer sein.
GET /health antwortet {"status":"ok"}, solange die Datenbank antwortet; der HEALTHCHECK des Images nutzt es.