Sans LOKI_CHAT, c'est désormais la façade qui tient la conversation ;
LOKI_CHAT=go la rend au Go (porte de sortie, aussi listée dans le compose
Unraid). Le Go la garde de toute façon si un réglage que la façade ne
sait pas encore honorer est posé (PROJ_SNAPSHOT, KEEP_TURN_IMAGES,
NUDGE_IN_TOOL, SIDE_SLOT, SLOT_PERSIST, PREWARM, motifs retry_patterns),
décidé au démarrage comme avant.
Vérifié de bout en bout avec les vrais binaires et un faux moteur, dans
les deux modes : deux tours (texte, puis appel d'outil), même état, même
journal rejoué, discussion intacte après relance, et un panneau perf
identique (complétions, tours, pertes, sonde du gabarit).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
L'image embarque loki-rs (étape Alpine, binaire musl statique) et
l'entrypoint en fait la porte d'entrée : `loki-rs serve` sur le port
public, le Go derrière lui sur 127.0.0.1:8091. LOKI_FACADE=0 revient à
l'ancien schéma si la façade pose problème.
Au démarrage, le loki-rs de l'image installe la dernière release
« rolling » dans /data/bin/<build>/ ; l'entrypoint prend ensuite loki et
loki-rs du même dossier (which-bin), et un lien dans /usr/local/sbin fait
que `docker exec loki loki …` vise lui aussi la version installée. C'est
toujours le loki-rs de l'image qui met à jour : un binaire publié
défectueux ne peut pas bloquer le correctif suivant.
CI : job Rust (fmt, clippy -D warnings, tests). Publication : la release
« rolling » part à chaque push sur main avec le même numéro de run que
l'image (LOKI_BUILD) ; IMAGE_ABI, source unique, empêche d'installer des
binaires qui exigent une image plus récente. manifest.json est envoyé en
dernier.
Message corrigé quand l'image est plus récente que la release : rien à
tirer dans ce cas.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- strataDetect mesure l'espace libre de /data/strata (et non /data) : un SSD
monté à cet endroit est celui qui compte pour l'installation.
- L'installeur reçoit XDG_CACHE_HOME=/data/strata/cache : les caches pip et
Hugging Face ne remplissent plus /root, c.-à-d. l'image Docker d'Unraid.
- docker-compose.unraid.yml + README : monter un pool SSD en /data/strata.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XLbFcZj6mJjDpWvCpcChGA
Strata (github.com/Niko1221/Strata, MIT) fait tourner Qwen3.8 Flash Next
(MoE 125 B) sur une carte de joueur en répartissant les experts entre VRAM,
RAM et disque. Intégration reprise d'AJEAN (backend_moe.go, « AJEAN MoE
1.0 ») : paquet figé de la release moe-v1.0, vérifié par SHA-256.
- backend_strata.go : détection de la machine, quant conseillé, installation
en tâche (même suivi que llama.cpp), preset ENGINE=strata, lancement du
serveur de Strata par `loki serve`, réglages d'un modèle installé
- pré-vol, vision, liste des presets, journal de chargement : Strata reconnu
- proxy OpenAI et relais : Host local pour Strata (il refuse un Host inconnu)
- benchmark et optimiseur refusés sur Strata (protocole propre à llama-server)
- UI : ligne Strata dans Paramètres → Moteur (visible aussi avec le moteur de
l'image), fenêtre d'installation et de réglages, moteur actif affiché
- image : python3 + python3-venv ; compose : memlock illimité
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
« Exclusive access » n'est pas un réglage qu'on passe à Yes sur la page du
partage : c'est un état, que Unraid 6.12 accorde quand « Permit exclusive
shares » est activé et que le partage vit tout entier sur un pool, sans
stockage secondaire (/mnt/user/<partage> devient un lien vers le pool). La
consigne précédente envoyait chercher une option introuvable.
- conseil, compose et README : le vrai chemin (Global Share Settings,
mover vers le pool puis Secondary = None, « Exclusive access : Yes »),
et redémarrer le conteneur, Docker ne résolvant le lien qu'au démarrage ;
- un seul chemin par montage fuse.shfs : /data/models répétait /data ;
- l'encart de l'UI, permanent tant que la cause dure, devient masquable
(localStorage, pour ce texte seulement — un autre conseil réapparaît).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Sur Unraid, /mnt/user/… n'est pas un disque mais shfs, un démon FUSE :
chaque fsync de loki.db et chaque page d'un gros MoE mmappé relue depuis
le disque (modèle plus gros que la RAM) le traverse, à chaque token. Rien
n'est perdu ni altéré, mais le décodage ralentit — sans que rien ne le
dise.
Loki ne déplace rien : changer le chemin hôte d'une installation donnerait
un /data vide. Il le voit et le dit, sur un ton d'information :
- sys_storagefuse.go lit /proc/self/mountinfo (type lu après le séparateur
« - », montage le plus long qui contient le chemin) pour LOKI_HOME et
chaque dossier de modèles ; Linux en conteneur seulement, mis en cache
une minute puisque /api/status est interrogé en boucle ;
- conseil en jaune au démarrage et champ « hint » de /api/status, affiché
en encart discret, distinct du bandeau rouge de perte de données ;
- compose Unraid et README : « Exclusive access » recommandé (même chemin,
FUSE court-circuité), /mnt/<pool> en option avancée avec migration
manuelle et mise en garde sur un pool inexistant (RAM).
La détection de thrash du cache de pages est laissée de côté : elle exige
un signal majflt calibré par modèle sur le serveur.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Depuis la protection anti-site-tiers (0.14.0), un accès par nom de domaine
derrière un reverse proxy, sans clé de pilotage, reçoit un 403 sur toute
l'API. L'interface restait vide : chaque appel échouait en silence dans la
console.
- Au premier 403, un bandeau fixe affiche la raison donnée par le serveur
et le correctif : LOKI_TRUSTED_HOSTS=<le nom affiché> dans les variables
du conteneur, ou une clé de pilotage.
- docker-compose.yml et docker-compose.unraid.yml exposent la variable
LOKI_TRUSTED_HOSTS, commentée.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Dockerfile 3 étapes : llama.cpp CUDA (flags de backend_build.go, sauf
GGML_NATIVE=OFF — l'image est bâtie sur un runner, pas sur la machine
cible), binaire Go statique, runtime CUDA léger (tini, git, nodejs pour
les serveurs MCP npx).
- docker-entrypoint.sh : sème BIN/HOST/PORT (+ MODEL/CTX/NGL depuis l'env,
au premier boot seulement), lance le moteur en supervision PID puis
'loki web' au premier plan. UI seule exposée (8090) ; le moteur (8080,
non authentifié) reste interne.
- Nouvelle commande 'loki config [get|set]' : configuration non interactive
(la config vit dans bbolt, pas dans un fichier plat).
- docker-compose.yml (build local, réservation GPU) + variante Unraid
(image GHCR, runtime nvidia) ; volumes /data (LOKI_HOME) et /models.
Un seul conteneur car llm_client.go joint le moteur sur localhost (hérité
de l'amont).
L'ancien Loki (FastAPI + React + Ollama) est remplacé par le fork d'AJEAN.
Tout reste accessible dans l'historique (git show bb4fb1b:backend/app/agent.py).
Backend :
- agent_config : num_ctx dans la config, envoyé à Ollama (0 = défaut modèle)
- ollama_client : méthode ps() (placement GPU/CPU via /api/ps)
- autotune : placement() lit size vs size_vram pour savoir si le modèle est sur GPU
- routes/config : POST /api/config/auto (détecte GPU + modèle, calcule et applique
num_ctx/max_tokens, renvoie la détection et le placement)
Frontend :
- client/store : autoTune(), état tuning + résultat
- SettingsView : bouton ⚡ Réglage auto, bannière de détection (GPU/VRAM,
contexte, placement GPU/CPU), slider Contexte (num_ctx)
Config :
- GPU_VRAM_MB / GPU_NAME pour déclarer la VRAM si Ollama est distant
Tests : recommandation (8B sur 12 Go -> ctx 32768), route /auto + persistance,
transmission num_ctx aux options Ollama, placement via /api/ps.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SVay7z3y7q2gEe54ByAE6N
Le conteneur écoutait sur 8717 alors que le mapping pointait host:8717 ->
conteneur:8080, d'où la connexion refusée. On standardise sur un seul numéro de
port (8717) identique dedans/dehors, et on laisse le HEALTHCHECK de l'image
gérer le bon port (suppression des healthcheck compose codés en dur sur 8080).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SVay7z3y7q2gEe54ByAE6N
- Sépare le port hôte (HOST_PORT, défaut 8717) du port interne du conteneur (8080)
- docker-compose.yml : mapping ${HOST_PORT:-8717}:8080
- docker-compose.unraid.yml : 8717:8080
- .env.example : HOST_PORT=8717
- README : références de port mises à jour
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SVay7z3y7q2gEe54ByAE6N
- .github/workflows/docker-publish.yml : build + push de ghcr.io/r0m1k3/loki
(linux/amd64, tags latest + sha, cache GHA) à chaque push sur main
- docker-compose.unraid.yml : utilise l'image préconstruite (plus de build/git
sur Unraid, simple pull)
- README : instructions Unraid mises à jour (image GHCR, visibilité du package)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SVay7z3y7q2gEe54ByAE6N
- docker-compose.unraid.yml : stack prête pour Unraid (Compose Manager),
build depuis le repo cloné dans appdata, volumes /mnt/user/appdata/loki,
OLLAMA_HOST à adapter, healthcheck
- README : section Installation sur Unraid (détection auto des modèles Ollama)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SVay7z3y7q2gEe54ByAE6N