Add COMFYUI_WORKFLOW_NODES env var to Open WebUI in both setup scripts.
This pre-fills the node ID mappings (Prompt=6, Model=4, Width/Height=5,
Steps/Seed=3) so users only need to upload the workflow JSON file —
the node mapping fields are already populated.
Previously users had to both upload the workflow AND manually fill in
6 node ID fields. Now it's just upload + save.
https://claude.ai/code/session_01PtYTPherSJaxDEVPgF6Nxu
Previously display-only: IMG_TIER/IMG_MODELS were detected but never
used. Now they drive actual behavior:
- Both setup scripts call setup-image-models.sh --auto after model
pulls, installing the right SD/SDXL/Flux model for the detected GPU
- INVOKEAI_PRECISION is now GPU-aware: bfloat16 for Ampere+ (compute
8.0+), float16 for Pascal+, auto fallback for older cards. Was
hardcoded to float16.
- local-ai-setup.sh now includes ComfyUI service + Open WebUI
integration (ENABLE_IMAGE_GENERATION=true, COMFYUI_BASE_URL) — was
completely missing, only laptop_full_setup.sh had it
- Added ComfyUI port 8188 to UFW firewall rules in local-ai-setup.sh
- Added comfyui-data/comfyui-output directories to mkdir loop
- Updated start.sh and final output to show ComfyUI URL
https://claude.ai/code/session_01PtYTPherSJaxDEVPgF6Nxu
- Both setup scripts now detect VRAM and determine which image gen
models the GPU can run (SD 1.5 at 4GB, SDXL at 8GB, Flux at 12-20GB)
- New setup-image-models.sh: interactive script that detects GPU,
shows available models with VRAM requirements, and installs into
InvokeAI and/or ComfyUI. Supports --auto for unattended install.
- Scales from 4GB cards through dual RTX 5000s to high-end 48GB cards
- README: added image gen VRAM tier table, expanded inpainting docs
with practical fix recipes (hands, fingers, eyes, backgrounds),
mask tips, and denoising strength guidance
- Setup end messages now show image gen capabilities and point to
setup-image-models.sh instead of manual model install instructions
https://claude.ai/code/session_01PtYTPherSJaxDEVPgF6Nxu
Setup script changes:
- All prompts now use whiptail dialogs with text fallback
- Q1b (SSH), Q2 (storage), Q3 (Kiwix), Q4b (firewall), Q5 (models),
Q6 (download), final confirm all converted
- Model tier selection uses radiolist with recommended tier pre-selected
- Custom model entry uses inputbox with current defaults pre-filled
- Fix speed_label: now shows actual VRAM needed (file size + 2GB overhead)
instead of misleading "fully in VRAM" for models that don't fit
- qwen3.5-35b-a3b MoE already in tier list (was there, now with accurate
VRAM estimate shown)
README changes:
- Add "Realistic expectations by model size" table
- 35B MoE highlighted as sweet spot for small GPUs
https://claude.ai/code/session_01PtYTPherSJaxDEVPgF6Nxu
- Add ComfyUI as optional service in setup wizard (alongside InvokeAI)
- Configure Open WebUI env vars for ComfyUI integration when selected
(ENABLE_IMAGE_GENERATION, IMAGE_GENERATION_ENGINE, COMFYUI_BASE_URL)
- Add ComfyUI docker service (ai-dock/comfyui, port 8188, GPU access)
- Add comprehensive image generation documentation to README:
- ComfyUI + Open WebUI setup steps (model install, workflow export, node mapping)
- AUTOMATIC1111 alternative setup
- Environment variables reference table
- VRAM considerations for simultaneous LLM + image gen
- Update all touchpoints: UFW rules, Caddyfile, start.sh URLs, volumes,
compose services, summary output, directory creation
- Note: InvokeAI does NOT integrate with Open WebUI natively (no compatible API)
ComfyUI is the recommended path for chat-integrated image generation
https://claude.ai/code/session_01PtYTPherSJaxDEVPgF6Nxu
Setup wizard ZIM checklist now includes:
- Stack Overflow, Ask Ubuntu, Super User, Unix & Linux SE, Server Fault
(was only Stack Overflow before)
- DevDocs and FreeCodeCamp moved up near the top
- List grouped: Dev & Sysadmin → Reference → Other
- Whiptail dialog height increased to fit all 22 items
Both whiptail (GUI) and plain terminal (fallback) lists match.
Download handlers added for all new SE sites.
https://claude.ai/code/session_01PtYTPherSJaxDEVPgF6Nxu
- Option 2 description: "Qwen2.5 · Qwen2.5-Coder" → "Qwen 3.5 (Feb 2026)"
- Default choice: 1 (Western) → 2 (Performance/Qwen 3.5)
- Recommended tier logic: use TOTAL_VRAM and match actual tier names
(4B/9B/35B/27B for Qwen 3.5, not old 7B/14B/22B/32B)
- Users with 6GB GPUs now see the 4B option marked "fast — fully in VRAM"
instead of having to pick Custom and type model names manually
https://claude.ai/code/session_01PtYTPherSJaxDEVPgF6Nxu
Context management for local models with limited windows:
- Context Tracker (community function): shows tokens used vs available,
progress bar, percentage remaining — so you see the cliff coming
- Checkpoint Summarization Filter: auto-summarizes old messages when
context fills up, like Claude's auto-compaction
- Both added as recommended post-install links in setup output
(Open WebUI Functions install with one click from the UI)
6GB GPU tier (Quadro P3300, GTX 1060, etc.):
- Qwen 3.5 4B at Q4_K_M = ~2.5GB weights, leaves 3.5GB for KV cache
- With Q8 KV cache: ~32K usable context on 6GB
- Better than squeezing 9B into nothing — more context > slightly smarter
https://claude.ai/code/session_01PtYTPherSJaxDEVPgF6Nxu
The model can now search before it generates:
MCP tools (available via Open WebUI + Claude Code):
- search_docs(query): searches Kiwix ZIM files (Wikipedia, Stack Overflow,
DevDocs, Arch Wiki) — instant, offline, no rate limits
- read_doc(path): reads full article content from Kiwix results
- web_search(query): DuckDuckGo search, no API key needed
Open WebUI native search:
- ENABLE_RAG_WEB_SEARCH=true + RAG_WEB_SEARCH_ENGINE=duckduckgo
- Switched from SearXNG (not in stack) to DDG (zero config)
Search priority: Kiwix first (offline, fast) → DDG fallback (live web)
All 3 setup scripts updated:
- duckduckgo-search added to mcp_requirements.txt
- KIWIX_URL=http://kiwix:80 added to MCP container env
- curl added to MCP container deps (for sync script)
- Open WebUI DDG search enabled by default
https://claude.ai/code/session_01PtYTPherSJaxDEVPgF6Nxu
Replace subshell ls expansion (which produces no args when /data is empty)
with a conditional: serve ZIM files if they exist, otherwise sleep infinity
so the container stays up gracefully until ZIM files are added.
https://claude.ai/code/session_012gDnantBmFTWZGCiKyjazx
SearXNG:
- Dropped from both setup scripts and docker-compose (Google/Startpage
block self-hosted instances by IP — not reliable enough to include)
- Removed all interactive safe-search and engine-selection prompts
- Removed Open WebUI RAG web-search env vars (ENABLE_RAG_WEB_SEARCH,
SEARXNG_QUERY_URL, etc.)
- Removed port 8888 from UFW rules, start.sh URLs, done output, and
the Caddyfile template
- Removed searxng/ from .gitignore (directory no longer created)
- configure-searxng-safesearch.sh kept in repo for optional manual use
Kiwix:
- Replace the blocking wait-loop (`until ls *.zim`) with a one-liner
that passes whatever ZIM files exist (or none) directly to kiwix-serve,
so the container starts immediately and shows an empty library page
rather than hanging until ZIMs are downloaded
https://claude.ai/code/session_012gDnantBmFTWZGCiKyjazx
All scripts now default BASE to their own directory (SCRIPT_DIR) instead
of ~/docker/ai-stack, so after a git clone the user never needs to change
folders — docker-compose.yml, .env, settings, and data dirs all live next
to the scripts.
configure-searxng-safesearch.sh and configure-storage.sh do the same for
standalone use (still honoured when called with BASE= from a parent script).
docker-compose.yml (generated by both setup scripts) gains a comment block
at the top listing the everyday docker compose commands:
up -d / down / restart / stop / logs -f / pull / ps
so the file itself is the reference for managing containers.
.gitignore added to exclude generated files (docker-compose.yml, .env,
requirements.txt, helper scripts) and data directories (workspace/, kiwix/,
searxng/, gitea/, etc.) from git tracking.
https://claude.ai/code/session_012gDnantBmFTWZGCiKyjazx
mcp_server.py / local-ai-setup.sh:
FastMCP.get_asgi_app() was removed in mcp 1.x — replace with
sse_app(), which returns the same Starlette ASGI app for SSE
transport. Fixes the crash loop the container was stuck in.
laptop_full_setup.sh Caddyfile:
$(hostname).local requires mDNS (Avahi/Bonjour) to resolve from a
proxy machine, which is often not available on all LAN clients.
Replace every occurrence with $LOCAL_IP (the machine's LAN IP)
so the generated Caddyfile.example works reliably regardless of
mDNS support.
https://claude.ai/code/session_012gDnantBmFTWZGCiKyjazx
Root cause of all 85 engines being disabled:
`3>&1 1>&2 2>&3 2>/dev/null` — the trailing `2>/dev/null` overwrites FD2
with /dev/null AFTER the FD swap, destroying the pipe that whiptail writes
selections to. User selections were silently discarded every time. Remove it.
Also: if whiptail exits 0 but returns empty string (all items unchecked),
fall back to pre-checked defaults rather than disabling everything.
ENABLE_MAP: unbound variable (configure-searxng-safesearch.sh):
bash < 4.4 treats `${!empty_assoc[@]}` as unbound under `set -u`.
Wrap for loops and mark_disabled key-check with set +u / set -u.
Add artic (Art Institute of Chicago) to image engine menus.
Add yandex images (defaults OFF for moderate/strict, same as yandex).
Update _SX_AUTOFF to include "yandex images" so re-enabling it works.
Update configure script engine category lists to match expanded menus.
https://claude.ai/code/session_012gDnantBmFTWZGCiKyjazx
- Radiolist first: Choose / All / Skip (ESC = skip)
- Checklist shows all 18 ZIMs with sizes; pre-checks any already
downloaded ZIMs so re-runs don't re-select what you have
- ZIM_PICKS now stores space-separated names (wikipedia, stackoverflow,
archlinux...) instead of numbers; dispatch updated to match
- Text fallback (no whiptail): same numbered list as before, converts
input numbers to names before dispatch
- Summary shows count and names of selected ZIMs
https://claude.ai/code/session_012gDnantBmFTWZGCiKyjazx
For both setup scripts and configure-searxng-safesearch.sh:
- Five whiptail checklist menus: Web · Images · Videos · News · Science
- Pre-populated ON/OFF based on the chosen safe-search level:
none → all engines ON
moderate/strict → no-safe-search engines (mojeek, yandex, baidu, naver,
invidious, piped, peertube, sepiasearch, flickr,
imgur, deviantart, dailymotion, vimeo) default OFF
- User can toggle any engine independently before confirming
- ESC on any menu restores defaults for that category (keeps them unchanged)
- If user re-enables an auto-disabled engine, --enable-engines is passed
to configure script to override the auto-disable
- Text fallback for non-interactive/headless installs
- Summary shows count of disabled engines instead of raw list
https://claude.ai/code/session_012gDnantBmFTWZGCiKyjazx
Setup (both scripts):
- Q6 asks safe-search level: none / moderate / strict
- Then asks which categories to disable: videos images news science social
- Then asks which engines to disable by name (duckduckgo, bing, etc.)
- Choices flow into SEARXNG_QUERY_URL &safesearch=N in docker-compose.yml
- SearXNG summary line added to laptop_full_setup.sh install plan
configure-searxng-safesearch.sh:
- Full rewrite: --disable-categories, --disable-engines, --enable-engines
- Category maps: videos / images / news / science / social engine lists
- --enable-engines overrides auto-disables (e.g. keep yandex on strict)
- Preserves existing secret key on update
- Creates settings.yml from scratch if missing (safe for setup use)
- Help flag (-h/--help)
https://claude.ai/code/session_012gDnantBmFTWZGCiKyjazx
- New configure-searxng-safesearch.sh: set strict/moderate/none level,
disable engines that can't enforce the chosen level (torrent sites,
mojeek, baidu, yandex, nvidious/piped/peertube video frontends),
updates &safesearch= in SEARXNG_QUERY_URL, and restarts searxng
- Add RAG_WEB_SEARCH_RESULT_COUNT=5 and RAG_WEB_SEARCH_CONCURRENT_REQUESTS=10
to Open WebUI env in both setup scripts
- Add &safesearch=0 to SEARXNG_QUERY_URL so the script can find/replace it
- Sync ENABLE_TOOL_SERVERS=true into laptop_full_setup.sh (was missing)
https://claude.ai/code/session_012gDnantBmFTWZGCiKyjazx
- Add WEBUI_URL to .env template and open-webui compose env so sessions
work correctly when served behind Caddy (or any reverse proxy)
- Fix Caddyfile.example to pass X-Forwarded-Proto/Host headers for Open WebUI
- Wrap kiwix-serve command in a wait loop so the container stays healthy
while ZIM files are still downloading (avoids 502 from Caddy)
https://claude.ai/code/session_012gDnantBmFTWZGCiKyjazx
When Docker containers write config files (e.g. searxng/settings.yml),
those files end up owned by root. write_if_new now falls back to
sudo tee when the destination file exists but is not writable.
https://claude.ai/code/session_012gDnantBmFTWZGCiKyjazx
- The "select which ZIMs" menu now fires during Q4 (upfront wizard),
alongside the yes/select/no choice, not after docker/models start
- Each ZIM entry shows [downloaded] if a matching .zim already exists
in KIWIX_DIR — skips re-downloading automatically via dl_zim check
- Download phase now uses the pre-captured ZIM_PICKS directly,
no interactive prompt mid-install
https://claude.ai/code/session_012gDnantBmFTWZGCiKyjazx
Both [2/6] and [3/6] prompts now show detected mount points as a
numbered list. Type 0 for default/Docker volume, or 1/2/3 to pick a
drive directly. Typing a path manually still works as fallback.
https://claude.ai/code/session_012gDnantBmFTWZGCiKyjazx
The tier table now shows 1–4 numbers so you type 1/2/3/4 instead of
typing "14B" or "32B". Tier names are still accepted as fallback.
Recommended tier is shown as a number (e.g. [2] instead of [14B]).
https://claude.ai/code/session_012gDnantBmFTWZGCiKyjazx
All interactive prompts now use numbered toggles (type a number to
toggle on/off, Enter to confirm) instead of requiring whiptail.
Removed whiptail from apt dependencies in ubuntu-post-install.sh.
https://claude.ai/code/session_012gDnantBmFTWZGCiKyjazx
- Top-level menu now just: Full system setup / AI stack
- AI stack opens a second whiptail checklist (same style as
ubuntu-post-install.sh) where each service is individually toggled:
Ollama (always on, core)
Open WebUI · RAG+ChromaDB · MCP Server · SearXNG
Gitea · InvokeAI · Portainer · Kiwix
- Kiwix moved from top-level into the AI stack service list
- Existing containers auto-detected and pre-ticked ON
- MCP dependency on RAG enforced automatically with a warning
- COMPOSE_SERVICES, Done URLs, and summary all driven by per-service
SVC_* flags so only selected services are started/shown
- Text toggle fallback for systems without whiptail
https://claude.ai/code/session_012gDnantBmFTWZGCiKyjazx
Replace fixed model defaults with an interactive wizard:
Origin preference:
1) Western-only — Codestral (Mistral 🇫🇷) · Phi4 · Mistral 7B
2) Performance-first — Qwen2.5 + Qwen2.5-Coder (top benchmarks)
3) Mixed — Western chat/reasoning, Qwen for coding only
4) Custom — free-form model names
Size tier table — speed estimated for the user's actual VRAM with no
hard limits (Ollama already uses all available VRAM via NUM_GPU=999):
✓ fast — fully in VRAM
~ good — fits with small overhang (~reading speed)
✗ slow — partial CPU offload
✗ very slow — heavy CPU offload
Recommended tier shown as suggestion based on VRAM, user can override.
pull-models.sh now bakes in the chosen model names at install time.
REASON_MODEL replaces hardcoded deepseek-r1:14b; skipped if empty or
same as chat model.
https://claude.ai/code/session_012gDnantBmFTWZGCiKyjazx
- Docker + Docker Compose check now runs on every invocation (not skipped
on updates), installing if missing — ensures the stack can always run
- Added Docker Compose plugin install as fallback if compose is missing
- NVIDIA Container Toolkit check also always runs (not update-gated)
- Added SSH key import wizard question: import public keys from GitHub
(gh:username) and/or Launchpad (lp:username) using ssh-import-id,
so the machine is accessible over SSH immediately after setup
https://claude.ai/code/session_012gDnantBmFTWZGCiKyjazx
Replace the single-choice component menu with a multi-select checklist
(whiptail if available, text-based toggle fallback). Users now pick any
combination of:
[*] Full system setup — runs ubuntu-post-install.sh (Ubuntu apps,
security hardening, backups, Docker services)
[*] AI stack — Ollama, Open WebUI, RAG, MCP, Gitea, InvokeAI
[*] Kiwix — Offline Wikipedia, Stack Overflow, Arch Wiki
This makes laptop_full_setup.sh the single entry point — run it once,
toggle what you need (like Ubuntu Server's tasksel), leave overnight.
https://claude.ai/code/session_012gDnantBmFTWZGCiKyjazx
Gather all setup choices upfront so users can answer questions once and
walk away. Changes:
- Setup wizard asks all questions before any installation begins:
1. Component selection (AI stack / Kiwix / both)
2. Ollama model storage (Docker volume or custom bind-mount path)
3. Kiwix ZIM storage location (detect drives with enough free space)
4. Firewall LAN subnet (auto-detected from current IP)
5. Model downloads (confirm GPU-matched models, optional DeepSeek-R1)
6. ZIM downloads (all / select / skip)
- Shows a summary and asks for confirmation before doing anything
- Ollama supports bind-mount to custom path (e.g. /mnt/ssd/ollama)
- Kiwix ZIM dir is configurable (separate large drive)
- Model pull runs unattended at end using upfront answer
- ZIM downloads integrated inline (no need to run kiwix_download.sh
separately) — background wget with progress log
https://claude.ai/code/session_012gDnantBmFTWZGCiKyjazx
Healthcheck tools (wget/curl) are not reliably available in the
chromadb image. Removing the healthcheck and switching rag-server
depends_on to service_started avoids the unhealthy container error.
https://claude.ai/code/session_012gDnantBmFTWZGCiKyjazx
- Show menu at startup to select: full stack, AI stack only, or Kiwix only
- Gate server files, SearXNG config, docker compose up, model pull,
and summary URLs based on selection
- Fix ChromaDB healthcheck: wget → curl, /api/v2/ → /api/v1/heartbeat
https://claude.ai/code/session_012gDnantBmFTWZGCiKyjazx
NVIDIA dropped the distro-specific repo URL in favour of a single
stable path. Also pass --yes to gpg --dearmor to avoid the interactive
overwrite prompt on re-runs.
https://claude.ai/code/session_012gDnantBmFTWZGCiKyjazx
- laptop_full_setup.sh now handles both fresh install and updates cleanly
(detects existing install, --force flag to overwrite config files)
- server.py: standalone RAG server with AST-aware code chunking (Python),
pattern-split for JS/TS/Go, /ingest/repo and /webhook/gitea|github endpoints
- mcp_server.py: new MCP server (port 8002/SSE) with Claude Code-equivalent
tools: bash, file ops, ripgrep search, git ops, Gitea API, GitHub API,
RAG repo ingest
- docker-compose: adds mcp-server service, workspace volume, env_file for tokens
- .env preserved on update (tokens never overwritten)
- GPU: OLLAMA_NUM_GPU=999 auto-adapts to any VRAM size (no hard-coded 6GB)
- ZIM downloads remain in kiwix_download.sh (separate, large files)
https://claude.ai/code/session_012gDnantBmFTWZGCiKyjazx