diff --git a/AGENTS.md b/AGENTS.md index 3b831b5..2bec806 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -8,10 +8,10 @@ one checkout per host, one deploy script. - **Dankserver** (192.168.0.235) — media/library stack (RomM, Copyparty, Calibre-Web, the *arr stack, Jellyfin) as bare containers, plus the - `frank-default-small` LLM service. + `frank-small` LLM service. - **Dankclaw** (192.168.0.143) — AI/search/development/observability stack (SearXNG via Gluetun, ComfyUI, OpenWebUI, Hermes, Gitea, Grafana, Prometheus, - Loki, Alloy, Pi-hole) plus the `frank-default-large` LLM service. Caddy on + Loki, Alloy, Pi-hole) plus the `frank-large` LLM service. Caddy on Dankclaw reverse-proxies both hosts. **2026-08-22 merge:** the former `vllmScripts` repository (LLM fleet scripts, @@ -26,9 +26,9 @@ host. | Target | Runtime | Service | Model | Port | |--------|---------|---------|-------|------| -| Dankserver | FreeToken v0.1.2 | frank-default-small | batsclamp Huihui-Qwen3.6-35B-A3B-abliterated-FP8 (block-fp8 e4m3 128x128, ~35 GB safetensors), experts host-RAM LRU, 262144 ctx / 4 concurrent, reasoning on | 7770 | -| Dankclaw | kingjones30/ROCmFPX llama.cpp (card-pinned fork) | frank-default-large | kingjones777 Qwen3.8-Flash-Next-ROCmFP4-STRIX (113.47 GiB single GGUF, Q4_0_ROCMFP4_STRIX, PLE streams via mmap), 401408 ctx / 2 slots, fa on, no spec decode, reasoning on | 7770 | -| Dankclaw | FastFlowLM (FLM) v1.0.1 (`flm serve`, dpkg `fastflowlm`) on the XDNA2 NPU | frank-default-sightsound | Gemma4-E4B-IT-NPU2 pack (vision + audio towers); whole local registry served on one port, per-request routing by exact FLM tag; `iommu=pt` boot arg mandatory (SVA bind needs enabled IOMMU) | 7771 | +| Dankserver | FreeToken v0.1.2 | frank-small | batsclamp Huihui-Qwen3.6-35B-A3B-abliterated-FP8 (block-fp8 e4m3 128x128, ~35 GB safetensors), experts host-RAM LRU, 262144 ctx / 4 concurrent, reasoning on | 7770 | +| Dankclaw | kingjones30/ROCmFPX llama.cpp (card-pinned fork) | frank-large | kingjones777 Qwen3.8-Flash-Next-ROCmFP4-STRIX (113.47 GiB single GGUF, Q4_0_ROCMFP4_STRIX, PLE streams via mmap), 401408 ctx / 2 slots, fa on, no spec decode, reasoning on | 7770 | +| Dankclaw | FastFlowLM (FLM) v1.0.1 (`flm serve`, dpkg `fastflowlm`) on the XDNA2 NPU | frank-npu | Gemma4-E4B-IT-NPU2 pack (vision + audio towers); whole local registry served on one port, per-request routing by exact FLM tag; `iommu=pt` boot arg mandatory (SVA bind needs enabled IOMMU) | 7771 | History: the 2026-08-17 redo retired the pipeline-parallel split and the FastFlowLM NPU endpoint. The 2026-08-18 swap retired the vLLM service on @@ -47,7 +47,7 @@ Qwen3.6-35B-A3B-FP8. On 2026-08-30 both services swapped again: Dankclaw to the kingjones STRIX model on the card's pinned kingjones30/ROCmFPX runtime, Dankserver to the Huihui abliterated FP8 checkpoint on FreeToken. On 2026-08-30 the NPU endpoint returned as -`frank-default-sightsound` — FLM v1.0.1 on XDNA2 serving sight+sound (see the +`frank-npu` — FLM v1.0.1 on XDNA2 serving sight+sound (see the Runtime & Troubleshooting section and its runbook). Runbooks: [serverAppConfigs-docs/LLM/index.md](serverAppConfigs-docs/LLM/index.md). Retired scripts live in `old/` (reference only) and `.AGENTTRASH/`. @@ -117,13 +117,13 @@ selected service and records its successful revision outside the checkout. ./scripts/deploy.sh dankclaw ./scripts/deploy.sh dankserver ./scripts/deploy.sh dankclaw --service searxng -./scripts/deploy.sh dankserver --service frank-default-small +./scripts/deploy.sh dankserver --service frank-small ./scripts/deploy.sh dankclaw --dry-run ``` A documentation-only change is a no-op. The LLM services are selected only by their own unit/env/serve files or the shared chat template, so unrelated -container changes cannot interrupt inference. `frank-default-npu` is relink-only +container changes cannot interrupt inference. `frank-npu` is relink-only when explicitly selected. Set `FRANK_SUDO_PW` for headless runs on a host without passwordless sudo @@ -263,10 +263,10 @@ ALWAYS bench using llama-bench for llama.cpp or vllm bench for vllm runtimes. DO NOT ROLL YOUR OWN BENCH UNLESS YOU CANNOT TEST THE DESIRED PARAMETER WITH THE OFFICIAL BENCHES. ASK THE USER BEFORE DEVIATING FROM THIS DIRECTIVE. 1. Stop the service before any benchmark: - `sudo systemctl stop frank-default-large` (Dankclaw) or - `sudo systemctl stop frank-default-small` (Dankserver). + `sudo systemctl stop frank-large` (Dankclaw) or + `sudo systemctl stop frank-small` (Dankserver). Then mask it to prevent the self-healing unit from restarting: - `sudo systemctl mask frank-default-large` (Dankclaw). + `sudo systemctl mask frank-large` (Dankclaw). **CRITICAL WARNING:** Do NOT use `systemctl disable` on these service units. On these hosts, `systemctl disable` doesn't just remove symlinks — it **deletes the unit file itself** from `/etc/systemd/system/`. You'd have to manually @@ -279,7 +279,7 @@ DO NOT ROLL YOUR OWN BENCH UNLESS YOU CANNOT TEST THE DESIRED PARAMETER WITH THE (the model + KV fill the card), so changes are validated directly against the service itself. 3. Restart the service when the bench completes: unmask, then start: - `sudo systemctl unmask frank-default-large && sudo systemctl start frank-default-large` (Dankclaw). + `sudo systemctl unmask frank-large && sudo systemctl start frank-large` (Dankclaw). 4. Verify health before reporting: `curl http://192.168.0.235:7770/health` or `curl http://192.168.0.143:7770/health`. @@ -289,7 +289,7 @@ DO NOT ROLL YOUR OWN BENCH UNLESS YOU CANNOT TEST THE DESIRED PARAMETER WITH THE The Pi agent reaches the fleet through `/home/dank/.pi/agent/models.json`. This file lives outside the repository. Each provider is one host endpoint. Each model `id` is the served alias. The two aliases are -`frank-default-small` (Dankserver `:7770`) and `frank-default-large` +`frank-small` (Dankserver `:7770`) and `frank-large` (Dankclaw `:7770`). The model `id` values are stable. The file @@ -310,7 +310,7 @@ When you rename a service or move a model to a new host, update ## Runtime & Troubleshooting -### frank-default-sightsound — FLM NPU sight+sound endpoint (Dankclaw, ACTIVE) +### frank-npu — FLM NPU sight+sound endpoint (Dankclaw, ACTIVE) The third inference endpoint on Dankclaw. The `flm serve` runtime (dpkg package `fastflowlm`, v1.0.1, binary `/usr/bin/flm`) serves the **whole local @@ -333,19 +333,19 @@ Hard requirements verified at first deploy (2026-08-30): bind needs PASID/SVA, which requires enabled IOMMU hardware. Fix applied: `iommu=pt` in `GRUB_CMDLINE_LINUX_DEFAULT` + reboot (passthrough keeps the iGPU default domain identity-mapped — zero DMA-translation overhead for - frank-default-large — while enabling IOMMU + PASID; PASID domains are + frank-large — while enabling IOMMU + PASID; PASID domains are paged regardless of the default-domain type). Never set `iommu=off` on this host again; it silently kills the NPU. - Health probe = `GET /v1/version` (FLM has no `/health` route). - Unit: `User=dank`, `LimitMEMLOCK=infinity` (FLM requires unlimited memlock), `Restart=on-failure`, `RestartSec=10`. Deploy via - `scripts/deploy.sh dankclaw --service frank-default-sightsound`. + `scripts/deploy.sh dankclaw --service frank-npu`. - Verified live at first deploy: image probe (red PNG as `image_url` data-URI → correct color answer, vision tower consumed the pixels) and an audio control-pair probe (tone WAV via `input_audio` consumed ~22 audio-tower tokens vs a text-only control). -Runbook: [serverAppConfigs-docs/LLM/frank-default-sightsound.md](serverAppConfigs-docs/LLM/frank-default-sightsound.md). +Runbook: [serverAppConfigs-docs/LLM/frank-npu.md](serverAppConfigs-docs/LLM/frank-npu.md). ### kingjones Qwen3.8-Flash-Next STRIX on kingjones30/ROCmFPX (Dankclaw, ACTIVE) The large service serves @@ -375,7 +375,7 @@ correct here — mmap pages ARE page cache) and **never pin the PLE tensor with `-ot`** (23 → 13.4 t/s). The 51.2B-param PLE table never enters GPU memory (~20 bytes/token-file per 500 decoded). On-host file sha256 verified == HF LFS oid `c6770d74...49fa`. Env -`scripts/frank-default-large.env`, serve `scripts/serve-frank-large.sh`. +`scripts/frank-large.env`, serve `scripts/serve-frank-large.sh`. Runbook: [serverAppConfigs-docs/LLM/kingjones-strix-rocmfp4.md](serverAppConfigs-docs/LLM/kingjones-strix-rocmfp4.md). @@ -416,9 +416,9 @@ validated `--memory-num-gpu-blocks-experts 2048 (never grow the expert pool). 262144 context, reasoning on (the checkpoint ships the froggeric fixed chat template — no override). FreeToken's API REQUIRES an explicit `"model"` field in chat requests -(422 without it). Env `scripts/frank-default-small.env`, serve +(422 without it). Env `scripts/frank-small.env`, serve `scripts/serve-frank-small.sh`. Runbook: -[serverAppConfigs-docs/LLM/freetoken-frank-default-small.md](serverAppConfigs-docs/LLM/freetoken-frank-default-small.md). +[serverAppConfigs-docs/LLM/freetoken-frank-small.md](serverAppConfigs-docs/LLM/freetoken-frank-small.md). **Serving status (2026-08-30):** swapped the model within the FreeToken runtime (official FP8 → Huihui abliterated FP8). ~40 tok/s verified on diff --git a/README.md b/README.md index aee8f80..cd48ec6 100644 --- a/README.md +++ b/README.md @@ -12,8 +12,8 @@ one deploy script. | Host | User | IP | Podman stack | LLM service | LLM port | |------|------|----|--------------|-------------|----------| -| dankserver | dank | 192.168.0.235 | media and library | frank-default-small (llama.cpp, Qwen3.6-35B-A3B) | 7770 | -| dankclaw | dank | 192.168.0.143 | AI, search, development, observability | frank-default-large (CIRU ROCmFPX, Qwen3.8-27B) | 7770 | +| dankserver | dank | 192.168.0.235 | media and library | frank-small (llama.cpp, Qwen3.6-35B-A3B) | 7770 | +| dankclaw | dank | 192.168.0.143 | AI, search, development, observability | frank-large (CIRU ROCmFPX, Qwen3.8-27B) | 7770 | ## Active Services @@ -22,7 +22,7 @@ one deploy script. | RomM | dankserver | romm.dankserver.local | 8085 | | Copyparty | dankserver | files.dankserver.local | 3923 | | Calibre-Web | dankserver | books.dankserver.local | 8083 | -| frank-default-small | dankserver | — (bare endpoint) | 7770 | +| frank-small | dankserver | — (bare endpoint) | 7770 | | SearXNG | dankclaw | search.dankclaw.local | 8081 | | ComfyUI | dankclaw | comfyui.dankclaw.local | 8188 | | OpenWebUI | dankclaw | chat.dankclaw.local | 3000 | @@ -30,7 +30,7 @@ one deploy script. | Gitea | dankclaw | gitea.dankclaw.local | 3001 | | Grafana | dankclaw | grafana.dankclaw.local | 3002 | | Prometheus | dankclaw | prometheus.dankclaw.local | 9090 | -| frank-default-large | dankclaw | — (bare endpoint) | 7770 | +| frank-large | dankclaw | — (bare endpoint) | 7770 | ## Structure diff --git a/dankclaw/hermes/config.yaml.example b/dankclaw/hermes/config.yaml.example index c1c6ddb..204d549 100644 --- a/dankclaw/hermes/config.yaml.example +++ b/dankclaw/hermes/config.yaml.example @@ -10,20 +10,20 @@ model: provider: dankclaw-large base_url: http://192.168.0.143:7770/v1 api_key: not-needed - default: frank-default-large + default: frank-large providers: dankclaw-large: api: http://192.168.0.143:7770/v1 discover_models: false models: - frank-default-large: + frank-large: context_length: 262144 dankserver-small: api: http://192.168.0.235:7770/v1 discover_models: false models: - frank-default-small: + frank-small: context_length: 163840 dankclaw-npu: api: http://192.168.0.143:7771/v1 @@ -36,18 +36,18 @@ providers: # custom endpoint shape and are retained here as a settings backup. auxiliary: vision: {provider: dankclaw-npu, model: gemma4-it:e4b, base_url: http://192.168.0.143:7771/v1} - web_extract: {provider: custom, model: frank-default-small, base_url: http://192.168.0.235:7770/v1} - compression: {provider: custom, model: frank-default-small, base_url: http://192.168.0.235:7770/v1} - skills_hub: {provider: custom, model: frank-default-small, base_url: http://192.168.0.235:7770/v1} - approval: {provider: custom, model: frank-default-small, base_url: http://192.168.0.235:7770/v1} - mcp: {provider: custom, model: frank-default-small, base_url: http://192.168.0.235:7770/v1} - title_generation: {provider: custom, model: frank-default-small, base_url: http://192.168.0.235:7770/v1} - memory_query_rewrite: {provider: custom, model: frank-default-small, base_url: http://192.168.0.235:7770/v1} - tts_audio_tags: {provider: custom, model: frank-default-small, base_url: http://192.168.0.235:7770/v1} - triage_specifier: {provider: custom, model: frank-default-small, base_url: http://192.168.0.235:7770/v1} - kanban_decomposer: {provider: custom, model: frank-default-small, base_url: http://192.168.0.235:7770/v1} - profile_describer: {provider: custom, model: frank-default-small, base_url: http://192.168.0.235:7770/v1} - curator: {provider: custom, model: frank-default-small, base_url: http://192.168.0.235:7770/v1} + web_extract: {provider: custom, model: frank-small, base_url: http://192.168.0.235:7770/v1} + compression: {provider: custom, model: frank-small, base_url: http://192.168.0.235:7770/v1} + skills_hub: {provider: custom, model: frank-small, base_url: http://192.168.0.235:7770/v1} + approval: {provider: custom, model: frank-small, base_url: http://192.168.0.235:7770/v1} + mcp: {provider: custom, model: frank-small, base_url: http://192.168.0.235:7770/v1} + title_generation: {provider: custom, model: frank-small, base_url: http://192.168.0.235:7770/v1} + memory_query_rewrite: {provider: custom, model: frank-small, base_url: http://192.168.0.235:7770/v1} + tts_audio_tags: {provider: custom, model: frank-small, base_url: http://192.168.0.235:7770/v1} + triage_specifier: {provider: custom, model: frank-small, base_url: http://192.168.0.235:7770/v1} + kanban_decomposer: {provider: custom, model: frank-small, base_url: http://192.168.0.235:7770/v1} + profile_describer: {provider: custom, model: frank-small, base_url: http://192.168.0.235:7770/v1} + curator: {provider: custom, model: frank-small, base_url: http://192.168.0.235:7770/v1} dashboard: # basic_auth intentionally omitted; its password_hash remains live-only. diff --git a/serverAppConfigs-docs/Architecture/Deployment Flow.md b/serverAppConfigs-docs/Architecture/Deployment Flow.md index a8bf996..71b29f9 100644 --- a/serverAppConfigs-docs/Architecture/Deployment Flow.md +++ b/serverAppConfigs-docs/Architecture/Deployment Flow.md @@ -44,8 +44,9 @@ graph LR ```bash ./scripts/deploy.sh dankclaw ./scripts/deploy.sh dankserver +./scripts/deploy.sh frankbook-pro --service qbittorrent # podman-machine target ./scripts/deploy.sh dankclaw --service searxng -./scripts/deploy.sh dankserver --service frank-default-small +./scripts/deploy.sh dankserver --service frank-small ./scripts/deploy.sh dankclaw --dry-run ``` @@ -61,12 +62,12 @@ service on the other host. |---|---|---| | Dankclaw compose services | `podman-compose -f dankclaw/compose.yaml up -d --no-deps NAME` | Recreates only `NAME`; Caddy is handled separately because it fronts both hosts. | | SearXNG, Gluetun, Valkey, OpenWebUI, Pi-hole, Gitea database/server | user Quadlet + `systemctl --user` | Installs the selected unit and restarts only the required dependency-coupled units. Gitea's web proxy is the canonical Caddy compose service. | -| `frank-default-large` | systemd + `systemctl` | Relinks and restarts only the large inference service; waits up to 20 minutes for `/health`. | -| `frank-default-small` | systemd + `systemctl` | Relinks and restarts only the small inference service; waits up to 20 minutes for `/health`. | +| `frank-large` | systemd + `systemctl` | Relinks and restarts only the large inference service; waits up to 20 minutes for `/health`. | +| `frank-small` | systemd + `systemctl` | Relinks and restarts only the small inference service; waits up to 20 minutes for `/health`. | | Dankserver media stack (RomM trio, Jellyfin, Calibre-Web, Copyparty) | user Quadlet + `systemctl --user` | Installs `dankserver//quadlet/*.container`, restarts the generated unit. The first cutover per service is idempotent: it retires the compose-era bare container, rescues any anonymous volume into the data root, and merge-moves `/opt/` to `/home/dank/Containers/` (mapped-uid roots move without chown). Steady state is restart-only. | The shared chat template maps to the inference service on the selected target. -The inactive `frank-default-npu` unit is relink-only when explicitly selected; +The inactive `frank-npu` unit is relink-only when explicitly selected; it is not restarted by an unrelated large-model deployment. ## Caddy safety diff --git a/serverAppConfigs-docs/Dankclaw/ComfyUI.md b/serverAppConfigs-docs/Dankclaw/ComfyUI.md index 6bb02fa..8c94fbd 100644 --- a/serverAppConfigs-docs/Dankclaw/ComfyUI.md +++ b/serverAppConfigs-docs/Dankclaw/ComfyUI.md @@ -2,7 +2,10 @@ ComfyUI is a node-based AI image generation engine. Workflows are built from nodes that load models, sample latents, and post-process images; everything is scriptable through a web UI and an API. -**Host:** Dankclaw — **Hostname:** `comfyui.dankclaw.local` — **Port:** 8188 — **Backend:** ROCm GPU (gfx1151) — **Docs:** https://github.com/Comfy-Org/ComfyUI +**Host:** Dankclaw — **Port:** `8188` published on the host; **no vhost and no +guard chain** — ComfyUI is LAN-only by construction (the Caddyfile routes no +name to it) — **Backend:** ROCm GPU (gfx1151) — **Docs:** +https://github.com/Comfy-Org/ComfyUI ## Facts diff --git a/serverAppConfigs-docs/Dankclaw/Dankclaw Stack.md b/serverAppConfigs-docs/Dankclaw/Dankclaw Stack.md index 4dc5085..a3ba501 100644 --- a/serverAppConfigs-docs/Dankclaw/Dankclaw Stack.md +++ b/serverAppConfigs-docs/Dankclaw/Dankclaw Stack.md @@ -12,11 +12,12 @@ timestamp: 2026-08-26 # Dankclaw Stack -Dankclaw (192.168.0.143) runs the AI, search, and development stack. It -hosts the LLM inference endpoint (`frank-default-large`, `:7770`, CIRU -ROCmFPX llama.cpp), the agent tools, the privacy search, and the -observability stack. The llama.cpp endpoint (`frank-default-small`, -`:7770`) runs on Dankserver (192.168.0.235). +Dankclaw (192.168.0.143) runs the AI, search, development, and observability +stack. Its LLM inference endpoint `frank-large` (`:7770`) is a ROCmFPX +llama.cpp fork serving the kingjones Qwen3.8-Flash-Next-ROCmFP4-STRIX GGUF on +the card's pinned runtime; an NPU endpoint (`frank-npu`, `:7771`, +FLM v1.0.1) serves sight+sound models. The completion endpoint +`frank-small` (FreeToken, `:7770`) runs on Dankserver (192.168.0.235). ```mermaid graph LR @@ -29,29 +30,36 @@ graph LR S --> V[Gluetun VPN] O --> L[llama.cpp dankserver :7770] O --> H[Hermes] - O --> E[CIRU llama.cpp :7770] + O --> E[frank-large :7770] ``` ## Services -| Service | Hostname | Port | Docs | -|---------|----------|------|------| -| SearXNG | search.dankclaw.local | 8081 | [[SearXNG]] | -| ComfyUI | comfyui.dankclaw.local | 8188 | [[ComfyUI]] | -| OpenWebUI | chat.dankclaw.local | 3005 | [[OpenWebUI]] | -| Hermes | hermes.dankclaw.local | 8090 | [[Hermes]] | -| Gitea | gitea.dankclaw.local | 3000 | [[Gitea]] | -| Grafana | grafana.dankclaw.local | 3002 | [[Grafana]] | -| Prometheus | prometheus.dankclaw.local | 9090 | [[Prometheus]] | -| Homepage | dankclaw.local | 80/443 | — | -| frank-default-large (host service, Dankclaw) | — | 7770 | [[deployment]] | -| frank-default-small (host service, Dankserver) | — | 7770 | [[deployment]] | +| Service | Vhost (guard status) | Port/route | Docs | +|---------|----------------------|------------|------| +| SearXNG | `search.franksdank.cloud` (guarded: Anubis → Authentik) | published by gluetun at `8081:8080`; searxng itself has no published port | [[SearXNG]] | +| ComfyUI | none — LAN-only by construction | `8188` | [[ComfyUI]] | +| OpenWebUI | `ai.franksdank.cloud` (exempt — own auth) | `3005 → 8080` | [[OpenWebUI]] | +| Hermes | `hermes.franksdank.cloud` (exempt by construction; internal-only via DNS absence) | webui `8787`; gateway publishes none | [[Hermes]] | +| Gitea | `gitea.franksdank.cloud` (exempt — git smart HTTP) | `3000`, SSH `2222` | [[Gitea]] | +| Grafana | `grafana.franksdank.cloud` (guarded) | Caddy routes post-auth to `grafana:3000` | [[Grafana]] | +| Prometheus | `prometheus.franksdank.cloud` (guarded) | `9090` | [[Prometheus]] | +| Loki | `loki.franksdank.cloud` (guarded; dedicated loki-proxy outpost provider with `internal_host = caddy:8017`) | `3100` | [[Observability]] | +| Seerr | `seerr.franksdank.cloud` (guarded) | Caddy routes post-auth to `seerr:5055` | [[Seerr]] | +| Homepage | `franksdank.cloud` + `www.` (root site; guarded for admin actions) | served by Caddy itself from `/srv/homepage` | — | +| Pi-hole | `pihole.franksdank.cloud` (basicauth edge, not the guard chain) | admin UI `8083`; DNS on `:53` LAN-wide | [[Pi-hole]] | +| frank-large (host service) | — | `7770` | [[deployment]] | +| frank-npu (host service) | — | `7771` (`/v1/version` health) | [[frank-npu]] | +| frank-small (host service, Dankserver) | — | `7770` | [[deployment]] | -The last two rows are bare-metal systemd services, not containers. This +The LLM rows are bare-metal systemd services, not containers. This repo owns their scripts, units, and knowledge base (see -[serverAppConfigs-docs/LLM/index.md](../LLM/index.md)). Current mapping (2026-08-22): -`frank-default-large` runs the CIRU ROCmFPX llama.cpp on Dankclaw; -`frank-default-small` runs the upstream llama.cpp on Dankserver. +[LLM fleet knowledge base](../LLM/index.md)). Current mapping (2026-09-03): +`frank-large` runs the kingjones Qwen3.8-Flash-Next-ROCmFP4-STRIX GGUF +on the card's pinned `kingjones30/ROCmFPX` llama.cpp build; +`frank-npu` runs FLM v1.0.1 on the XDNA2 NPU; +`frank-small` runs FreeToken v0.1.2 serving +Huihui-Qwen3.6-35B-A3B-abliterated-FP8 on Dankserver. ## Boot Persistence diff --git a/serverAppConfigs-docs/Dankclaw/Gitea.md b/serverAppConfigs-docs/Dankclaw/Gitea.md index 148153b..22039c6 100644 --- a/serverAppConfigs-docs/Dankclaw/Gitea.md +++ b/serverAppConfigs-docs/Dankclaw/Gitea.md @@ -63,9 +63,16 @@ The containers use the quadlet fresh-start model. A stop removes the container ( ## Secrets -The database password lives in `/opt/gitea/.env` on the host (mode 0600). The quadlet files reference it with `EnvironmentFile=`. The password never enters this repository. Placeholders live in [`dankclaw/gitea/.env.example`](../../dankclaw/gitea/.env.example). +The database password lives in `/home/dank/Containers/gitea/env` on the host +(mode 0600); `gitea-postgres.container` and `gitea-server.container` load it +via `EnvironmentFile=` (verified from the live units — the `${GITEA_DB_PASSWORD}` +placeholders are expanded by systemd at start). The password never enters this +repository. Placeholders live in +[`dankclaw/gitea/.env.example`](../../dankclaw/gitea/.env.example). -Do not change the password in place. Change the PostgreSQL role first, then update `/opt/gitea/.env` and the `[database] PASSWD` line in the app.ini (see Gotchas), then restart the stack. +Do not change the password in place. Change the PostgreSQL role first, then +update the env file and the `[database] PASSWD` line in the app.ini (see +Gotchas), then restart the stack. ## Configuration files @@ -73,23 +80,28 @@ Do not change the password in place. Change the PostgreSQL role first, then upda |------|----------|-----------| | Quadlet units | `~/.config/containers/systemd/gitea-{postgres,server}.container`, `gitea.network` | [`dankclaw/gitea/quadlet/`](../../dankclaw/gitea/quadlet/) | | Caddyfile | `/home/dank/Containers/caddy/Caddyfile` | [`dankclaw/Caddyfile`](../../dankclaw/Caddyfile) | -| Secrets | `/opt/gitea/.env` (0600) | [`dankclaw/gitea/.env.example`](../../dankclaw/gitea/.env.example) | +| Secrets | `/home/dank/Containers/gitea/env` (0600; loaded via `EnvironmentFile=`) | [`dankclaw/gitea/.env.example`](../../dankclaw/gitea/.env.example) | After editing a repo copy, deploy through `scripts/deploy.sh dankclaw`. The Gitea database/server units are installed from this directory; the canonical Caddy and its rendered Caddyfile are deployed as the separate `caddy` service. Do not manually recreate the retired `gitea-caddy` unit. ## Data volumes +Per the live quadlet units (`Volume=` lines): + | Container path | Host path | Contents | |----------------|-----------|----------| -| `/data` | `/opt/gitea/data/gitea-gitea` | Git repositories, app.ini, attachments | -| `/var/lib/postgresql/data` | `/opt/gitea/data/gitea-postgres` | PostgreSQL data | +| `/data` | `/home/dank/Containers/gitea/data` | Git repositories, app.ini, attachments | +| `/var/lib/postgresql/data` | `/home/dank/Containers/gitea/postgres` | PostgreSQL data | -Back up `/opt/gitea/data/` (tar) or `pg_dump` the database. See the knowledge base page [[Gitea]]. +Back up `/home/dank/Containers/gitea/` (tar) or `pg_dump` the database. See the knowledge base page [[Gitea]]. ## Gotchas -- **app.ini wins over env vars.** Gitea writes `/data/gitea/conf/app.ini` (host: `/opt/gitea/data/gitea-gitea/gitea/conf/app.ini`) on first start. The `[database] HOST` and `PASSWD` lines persist and override the `DATABASE_HOST`/`DATABASE_PASSWD` env vars. When you rename the database container, edit the `HOST` line. -- **The files in the data directory are owned by host UID 100999**, not `dank` (rootless ID mapping: container uid 1000 → host 100999). Edit them inside the container with `podman exec --user 1000 gitea-server ...`. +- **Data files are owned by `dank` (uid 1000), not root.** The quadlet units run + podman in the user manager with no `--user`/UserNS override, so container uid + 1000 is literally dank's host uid — there is no subuid offset for these + containers. Edit files as the owning user with + `podman exec --user 1000 gitea-server ...`. - **The host auto-reboots.** `unattended-upgrades` reboots Dankclaw when a package needs it. The quadlet units make Gitea survive that. See the 2026-08-16 incident below. - **Port 3000 vs 3001.** The live host port is 3000. The full-stack [`dankclaw/compose.yaml`](../../dankclaw/compose.yaml) maps 3001. Align the two before deploying the full stack. - **Legacy compose retired.** `/opt/gitea/podman-compose.yml` is retired to `/opt/gitea/.deprecated/`. Do not run it. Its containers collide with the Quadlet units on ports 3000 and 2222. diff --git a/serverAppConfigs-docs/Dankclaw/Hermes.md b/serverAppConfigs-docs/Dankclaw/Hermes.md index 749fce0..ba96491 100644 --- a/serverAppConfigs-docs/Dankclaw/Hermes.md +++ b/serverAppConfigs-docs/Dankclaw/Hermes.md @@ -2,7 +2,11 @@ Hermes is the self-improving AI agent from Nous Research. It runs in a terminal, Telegram, Discord, Slack, WhatsApp, or Signal, and keeps a persistent learning loop: it creates skills from experience, searches past conversations, and builds a model of the user across sessions. -**Host:** Dankclaw — **Hostname:** `hermes.dankclaw.local` — **Docs:** https://hermes-agent.nousresearch.com/docs +**Host:** Dankclaw — the gateway itself publishes **no port** (it runs in the +host network namespace and dials the Signal daemon at `127.0.0.1:8080`); the +user-facing web surface is [[Hermes-WebUI]] on `:8787`, reached via +`hermes.franksdank.cloud` — internal-only by DNS absence (no public Porkbun A +record) — **Docs:** https://hermes-agent.nousresearch.com/docs **Persistent state:** `/home/dank/Containers/hermes/data` on Dankclaw, bind-mounted at `/data` in all three Hermes containers (gateway, webui, dashboard). Each @@ -33,9 +37,9 @@ is not durable. The tracked, sanitized configuration baseline is `0.0.0.0:8080`, so the Signal HTTP API is reachable from the whole LAN. - The data volume persists skills, memory, and session history. - Hermes has two named local providers: `dankclaw-large` reaches - `http://192.168.0.143:7770/v1` and exposes `frank-default-large`; + `http://192.168.0.143:7770/v1` and exposes `frank-large`; `dankserver-small` reaches `http://192.168.0.235:7770/v1` and exposes - `frank-default-small`. + `frank-small`. - The live `config.yaml` contains secrets and user state and is not committed; the tracked example is the sanitized backup of its non-secret settings. @@ -50,7 +54,7 @@ is not durable. The tracked, sanitized configuration baseline is ## Gotchas - Hermes is under active development; pin the image tag for reproducibility. -- Model choice drives quality; the local `frank-default-large` (Dankclaw, 7770) is the intended backend. +- Model choice drives quality; the local `frank-large` (Dankclaw, 7770) is the intended backend. - Do not expose the gateway without auth — put it behind [[Caddy]] with basic auth. ## Browser automation (Chrome DevTools Protocol daemon) diff --git a/serverAppConfigs-docs/Dankclaw/OpenWebUI.md b/serverAppConfigs-docs/Dankclaw/OpenWebUI.md index fed099d..490f173 100644 --- a/serverAppConfigs-docs/Dankclaw/OpenWebUI.md +++ b/serverAppConfigs-docs/Dankclaw/OpenWebUI.md @@ -2,32 +2,42 @@ OpenWebUI is a self-hosted chat interface for LLMs. It connects to OpenAI-compatible endpoints (vLLM, llama.cpp, Ollama) and adds RAG, plugins, tool calling, and multi-user support. -**Host:** Dankclaw — **Port:** 3005 (host) → 8080 (container) — **Boot-persistent:** Quadlet — **Docs:** https://github.com/open-webui/open-webui +**Host:** Dankclaw — **Port:** 3005 (host) → 8080 (container) — **Vhost:** +`ai.franksdank.cloud` routes straight to `192.168.0.143:3005` (unguarded — +OpenWebUI enforces its own auth) — **Boot-persistent:** Quadlet — **Docs:** +https://github.com/open-webui/open-webui ## Facts | Item | Value | |------|-------| -| Image | `ghcr.io/open-webui/open-webui:main` (CPU build; Dankclaw is CPU-only) | +| Image | `ghcr.io/open-webui/open-webui:main` (verified from the live quadlet unit) | | Port | 3005 (host) → 8080 (container). Port 3000 is Gitea's HTTP, so it is not usable. | | Data volume | `/home/dank/Containers/open-webui/data` → `/app/backend/data` | -| Default backend | CIRU llama.cpp on Dankclaw `:7770` = `frank-default-large` (via host LAN IP `192.168.0.143:7770`) | +| Default backend | `frank-large` on Dankclaw `:7770` (ROCmFPX llama.cpp fork — see the LLM knowledge base below) — reached via host LAN IP `192.168.0.143:7770` | | Network | Pinned bridge `systemd-open-webui` (`10.89.3.0/24`, gateway `10.89.3.1`) — see [History](#history) | | Persistence | Quadlet unit `open-webui.service`; `[Install] WantedBy=default.target` | | Deploy | `scripts/deploy-open-webui-quadlet.sh dankclaw` | ## The LLM backends -The fleet runs two OpenAI-compatible endpoints. This mapping is the **live** state (verified 2026-08-22). Both services listen on `:7770`, distinguished by host. On 2026-08-22 `frank-default-large` moved from `:52625` to `:7770`. +The fleet runs two OpenAI-compatible endpoints. This mapping is the **live** +state (verified 2026-09-03). Both services listen on `:7770`, distinguished by +host; `frank-large` moved from `:52625` to `:7770` on 2026-08-22. | Endpoint | Model name | Host | Capability | -|----------|-----------|------|-----------| -| `:7770` (CIRU llama.cpp) | `frank-default-large` | Dankclaw | completion | -| `:7770` (llama.cpp) | `frank-default-small` | Dankserver | completion, multimodal | +|----------|-----------|------|------------| +| `:7770` (ROCmFPX llama.cpp fork) | `frank-large` | Dankclaw | completion | +| `:7770` (FreeToken v0.1.2) | `frank-small` | Dankserver | completion, multimodal | -The default connection points at the local vLLM (`frank-default-large`), so chat stays on-host. To add the other backend, open **Admin → Connections** in the UI and point an OpenAI connection at `http://192.168.0.235:7770/v1` (key `none`). +The default connection points at the on-host endpoint (`frank-large`). +To add the other backend, open **Admin → Connections** in the UI and point an +OpenAI connection at `http://192.168.0.235:7770/v1` (key `none`). -> Both endpoints are bare-metal systemd services managed by this repository (the former `vllmScripts` repo, merged in 2026-08-22). Model swaps, context sizing, and spec tuning happen here. See the [LLM knowledge base](../LLM/index.md). +> Both endpoints are bare-metal systemd services managed by this repository +(the former `vllmScripts` repo, merged in 2026-08-22). Model swaps, context +sizing, and spec tuning happen there. See the [LLM knowledge +base](../LLM/index.md). ## Boot persistence (Quadlet) @@ -58,7 +68,7 @@ The quadlet carries a built-in healthcheck (30s interval, 3 retries, 300s start ## Gotchas -- Use the non-CUDA image on this CPU-only host. +- The image tracks upstream `main`; pin a digest in the quadlet unit if reproducible rollback matters more than tracking. (The old "CPU-only host" framing is stale: this APU runs the gfx1151 ROCm build — see [[ComfyUI]].) - The default admin account is created on first login; secure it immediately. - If the backend is loading (3–8 minute model load), OpenWebUI shows connection errors until the model is ready. - The LLM is reached via the host LAN IP `192.168.0.143:7770`, not the bridge gateway: the gateway (`10.89.3.1`) lives in the rootless netns, while llama-server runs in the host netns, so the gateway refuses. `host.containers.internal` is slirp4netns-only and does not resolve on a bridge either. To reach the Dankserver backend, use the LAN address `192.168.0.235:7770`. diff --git a/serverAppConfigs-docs/Dankclaw/Postgres.md b/serverAppConfigs-docs/Dankclaw/Postgres.md index d1aa36a..f34a352 100644 --- a/serverAppConfigs-docs/Dankclaw/Postgres.md +++ b/serverAppConfigs-docs/Dankclaw/Postgres.md @@ -10,7 +10,7 @@ PostgreSQL is the database backend for Gitea. It runs on the same podman network |------|-------| | Image | `docker.io/library/postgres:16-alpine` | | Port | 5432 (internal only) | -| Data volume | bind mount at `/var/lib/postgresql/data` | +| Data volume | `/home/dank/Containers/gitea/postgres:/var/lib/postgresql/data` (live bind, verified from the unit) | ## Configuration @@ -42,9 +42,13 @@ environment: The live `app.ini` on the host overrides env vars. When you rename the database container, update its `[database] HOST` line. See [[Gitea]] Gotchas. -## Migration +## Layout (current) -The live Gitea stack on Dankclaw already runs this image with the data at `/opt/gitea/data/gitea-postgres`. The migration keeps the bind mount in place; see [[Gitea]]. +The live `gitea-postgres` unit mounts its data at +`/home/dank/Containers/gitea/postgres:/var/lib/postgresql/data` — the old +`/opt/gitea/data/gitea-postgres` compose-era path is gone. Secrets come from +the host-local env file `/home/dank/Containers/gitea/env` (0600) via +`EnvironmentFile=`; `POSTGRES_PASSWORD` never enters this repo. See [[Gitea]]. ## Healthcheck diff --git a/serverAppConfigs-docs/Dankclaw/SearXNG.md b/serverAppConfigs-docs/Dankclaw/SearXNG.md index b9e52c0..7e0ed8d 100644 --- a/serverAppConfigs-docs/Dankclaw/SearXNG.md +++ b/serverAppConfigs-docs/Dankclaw/SearXNG.md @@ -30,14 +30,19 @@ Port publishing happens on the **gluetun** unit, not on searxng. See [[Gluetun]] The trio runs as quadlet units, not podman-compose, so it starts at boot. The unit files live in `searxng/quadlet/` and install to `~/.config/containers/systemd/`. +The units live in `dankclaw/searxng/quadlet/` and install to +`~/.config/containers/systemd/` on Dankclaw (verified live): + | Unit file | Service | Role | |-----------|---------|------| -| `searxng.network` | `searxng-network.service` | DNS-enabled bridge, subnet pinned to 10.89.2.0/24 | -| `gluetun.container` | `gluetun.service` | WireGuard tunnel; publishes 8081:8080 | -| `searxng-valkey.container` | `searxng-valkey.service` | Valkey cache, alias `valkey` | -| `searxng.container` | `searxng.service` | Reuses gluetun's netns; publishes no port | +| `searxng.network` | generated network service | DNS-enabled bridge; the created network is named `systemd-searxng`, subnet pinned to 10.89.2.0/24 | +| `gluetun.container` | `gluetun.service` | WireGuard tunnel (env-file secrets); publishes `8081:8080` — the only published port in the trio | +| `searxng-valkey.container` | `searxng-valkey.service` | Valkey cache on the searxng network, alias `valkey` (see [[Valkey]]) | +| `searxng.container` | `searxng.service` | `Network=gluetun.container` — joins the tunnel's netns, so it publishes no port of its own; reached through gluetun's 8081 | -gluetun and valkey join the searxng network. searxng reuses gluetun's netns and reaches valkey by name on that network. Each unit sets `WantedBy=default.target`. User linger is on, so the units start at boot. +gluetun and valkey join the searxng network. searxng reuses gluetun's netns +and reaches valkey by name on that network. Each unit sets +`WantedBy=default.target`. User linger is on, so the units start at boot. Deploy with `scripts/deploy-searxng-quadlet.sh dankclaw`. It copies the units, daemon-reloads, enables them, and starts them in dependency order. @@ -112,7 +117,12 @@ Why so many ranges: rootless podman strips the client IP on published-port hits. The rate limiter's JSON cap is `API_MAX = 4` requests per IP per hour. The constant is hardcoded in Python (`searx/botdetection/ip_limit.py`). It cannot be raised from `limiter.toml`. `pass_ip` is the only bypass. This is what lets 4 parallel subagents poll the JSON API at full rate without a 429. -Reach SearXNG through Caddy (`search.dankclaw.local`) for browser use. A local subagent can hit the published port directly because its slirp source is now trusted. The searxng subnet 10.89.2.0/24 is in `trusted_proxies`, so Caddy's `X-Forwarded-For` is honored. The subnet is pinned in `searxng.network`, so it stays stable across reboots. +Reach SearXNG through Caddy (`search.franksdank.cloud`, guarded) for browser +use. A local subagent can hit the published port directly because its +slirp/loopback/LAN sources are in `pass_ip`. The searxng network +(`systemd-searxng`, 10.89.2.0/24) is in `trusted_proxies`, so Caddy's +`X-Forwarded-For` is honored. The subnet is pinned in `searxng.network`, so it +stays stable across reboots. ## Unblocking Google & Search Providers diff --git a/serverAppConfigs-docs/Dankserver/ARR-Stack.md b/serverAppConfigs-docs/Dankserver/ARR-Stack.md index ad3231c..ec76c83 100644 --- a/serverAppConfigs-docs/Dankserver/ARR-Stack.md +++ b/serverAppConfigs-docs/Dankserver/ARR-Stack.md @@ -1,8 +1,24 @@ +--- +type: reference +title: *arr Stack +description: The *arr automation stack (Prowlarr, Sonarr, Radarr, Lidarr, Readarr, qBittorrent) on FrankBook-Pro — topology, wiring, auth posture, and gotchas. +tags: [arr-stack, prowlarr, sonarr, radarr, lidarr, readarr, qbittorrent, frankbook-pro] +timestamp: 2026-09-03T00:00:00Z +--- + # *arr Stack -The *arr suite is a collection of automated media management tools for Usenet and BitTorrent. For Dankserver — which runs Copyparty, Calibre-Web, RomM, and Jellyfin — the *arr stack provides automatic downloading and library management that Copyparty alone does not cover: quality profile enforcement, series/movie discovery, metadata enrichment, and automated file organization. +The *arr suite is a collection of automated media management tools for Usenet +and BitTorrent. The stack runs on **FrankBook-Pro** — the Mac mini that fronts +this household's downloads — as quadlet units inside its podman machine, not on +Dankserver. It provides automatic downloading and library management that +Copyparty alone does not cover: quality profile enforcement, series/movie +discovery, metadata enrichment, and automated file organization. -The core chain is: **Prowlarr** (indexer API aggregator) → **Sonarr/Radarr/Lidarr/Readarr** (media-specific managers) → **qBittorrent** (download client) → **Jellyfin** (media server scan → auto-refresh). +The core chain is: **Prowlarr** (indexer API aggregator) → +**Sonarr/Radarr/Lidarr/Readarr** (media-specific managers) → **qBittorrent** +(download client, sharing the [[Gluetun]] WireGuard tunnel netns) → +**Jellyfin** (media server scan → auto-refresh). ## Service Overview @@ -12,334 +28,59 @@ The core chain is: **Prowlarr** (indexer API aggregator) → **Sonarr/Radarr/Lid | Radarr | Movie management | `lscr.io/linuxserver/radarr:latest` | 7878 | 512 MB | | Sonarr | TV show management | `lscr.io/linuxserver/sonarr:latest` | 8989 | 512 MB | | Lidarr | Music management | `lscr.io/linuxserver/lidarr:latest` | 8686 | 256 MB | -| Readarr | Ebook/audiobook management | `lscr.io/linuxserver/readarr:latest` | 8787 | 256 MB | -| qBittorrent | Torrent download client | `lscr.io/linuxserver/qbittorrent:latest` | 8080 | 512 MB | -| Jackett | Indexer proxy (optional) | `lscr.io/linuxserver/jackett:latest` | 9117 | 256 MB | -| Whisparr | NSFW movie management (optional) | `lscr.io/linuxserver/whisparr:latest` | 6969 | 256 MB | +| Readarr | Ebook/audiobook management | `lscr.io/linuxserver/readarr:amd64-1.0.980` (pinned — LSIO ships no untagged `latest` for readarr) | 8787 | 256 MB | +| qBittorrent | Torrent download client | `lscr.io/linuxserver/qbittorrent:4.6.7` (pinned; see [[qBittorrent]]) | 8080 (published by the gluetun unit) | 512 MB | -**Minimum total RAM:** ~3 GB for full stack (headroom recommended). +Jackett and Whisparr were evaluated as optional extras but never deployed +(no unit, no vhost, no live container). -## Architecture +## Deployment shape (current) -```mermaid -graph LR - I[Indexers
Torrents, Usenet] --> P[Prowlarr
Indexer Manager] - P --> S[Sonarr
TV] - P --> R[Radarr
Movies] - P --> L[Lidarr
Music] - P --> Rd[Readarr
Books] - S --> Q[qBittorrent] - R --> Q - L --> Q - Rd --> Q - Q --> M1[/tv/] - Q --> M2[/movies/] - Q --> M3[/music/] - Q --> M4[/books/] - M1 --> J[Jellyfin] - M2 --> J - M3 --> J - M4 --> CW[Calibre-Web] -``` +Each service is a quadlet `.container` unit in this repo under +`frankbook-pro//quadlet/`, installed inside the podman machine at +`/home/core/.config/containers/systemd/.service` by the frankbook-pro +handler in `scripts/deploy-remote.sh`. Every unit runs with +`PUID=0 PGID=0 TZ=America/Los_Angeles UMASK_SET=022`, mounts its config root at +`/Volumes/COMPLETE/-data:/config`, publishes its API port on the host, and +runs `Restart=always` with `TimeoutStartSec=900`. -## Docker Compose +qBittorrent is special: it shares the [[Gluetun]] container's network namespace +(`Network=gluetun.container`) so torrent egress never touches the residential +IP. A netns-sharer publishes no ports of its own — qB's WebUI (8080) and +BitTorrent port (6881 TCP+UDP) are published on the gluetun unit instead. -```yaml -networks: - appnet: - driver: bridge +## Historical design-era compose (retired) -services: - prowlarr: - image: lscr.io/linuxserver/prowlarr:latest - container_name: prowlarr - restart: unless-stopped - environment: - - PUID=1000 - - PGID=1000 - - TZ=America/New_York - - UMASK_SET=022 - volumes: - - /opt/prowlarr/config:/config - - /mnt/media/downloads:/downloads:ro - ports: - - "9696:9696" - networks: [appnet] +The original design deployed the stack on Dankserver via +`dankserver/compose.yaml` with `/opt//config` data roots and +`TZ=America/New_York`. That layout is retired; `dankserver/compose.yaml` is +kept as reference only. Reality (unit files above) wins: data roots are the +Mac's `/Volumes/COMPLETE` (completed media) and `/Volumes/INCOMPLETE` +(in-flight downloads) volumes, mounted into qB at identical paths, and every +unit runs `TZ=America/Los_Angeles`. - radarr: - image: lscr.io/linuxserver/radarr:latest - container_name: radarr - restart: unless-stopped - environment: - - PUID=1000 - - PGID=1000 - - TZ=America/New_York - - UMASK_SET=022 - volumes: - - /opt/radarr/config:/config - - /mnt/media/movies:/movies - - /mnt/media/downloads:/downloads - ports: - - "7878:7878" - networks: [appnet] +## Access / auth posture - sonarr: - image: lscr.io/linuxserver/sonarr:latest - container_name: sonarr - restart: unless-stopped - environment: - - PUID=1000 - - PGID=1000 - - TZ=America/New_York - - UMASK_SET=022 - volumes: - - /opt/sonarr/config:/config - - /mnt/media/tv:/tv - - /mnt/media/downloads:/downloads - ports: - - "8989:8989" - networks: [appnet] +There is **no Caddy vhost for any arr app** — the *arr stack is exempt by +construction from the Anubis guard chain (its own auth). The stack is reached +directly by IP:port on the LAN (`http://:8989` etc.). - lidarr: - image: lscr.io/linuxserver/lidarr:latest - container_name: lidarr - restart: unless-stopped - environment: - - PUID=1000 - - PGID=1000 - - TZ=America/New_York - - UMASK_SET=022 - volumes: - - /opt/lidarr/config:/config - - /mnt/media/music:/music - - /mnt/media/downloads:/downloads - ports: - - "8686:8686" - networks: [appnet] +Auth-config history (verified live 2026-08-29): all five arrs shipped with +`AuthenticationMethod=None` **plus** `AuthenticationRequired=Enabled`. On the +v1 (.NET) apps that combo is self-contradictory — UI Save is permanently +disabled and any settings save throws `DryIoc.ScopedItemException` inside +`AuthorizationMiddleware` (500 sprawl on every page after restart). The valid +representation of "no auth" in v1 is **absence of the `` +key**, not the literal string `Disabled` — readarr's config (key absent) booted +clean while its three siblings (key=`Disabled`) 500-sprawled, which is how it +was caught. Fix applied live: key deleted on sonarr/radarr/lidarr/prowlarr, +containers restarted, all five verified serving. Posture = zero-auth arrs on +LAN and WAN; the Anubis wall guards homepage/search/hermes/prometheus/romm/files +but **not** the arrs — first-account-wins is the current race condition if that +ever flips to `External` auth (needs an IdP first; auth method choice remains an +operator decision). - readarr: - image: lscr.io/linuxserver/readarr:latest - container_name: readarr - restart: unless-stopped - environment: - - PUID=1000 - - PGID=1000 - - TZ=America/New_York - - UMASK_SET=022 - volumes: - - /opt/readarr/config:/config - - /mnt/media/books:/books - - /mnt/media/downloads:/downloads - ports: - - "8787:8787" - networks: [appnet] - - qbittorrent: - image: lscr.io/linuxserver/qbittorrent:latest - container_name: qbittorrent - restart: unless-stopped - environment: - - PUID=1000 - - PGID=1000 - - TZ=America/New_York - - UMASK_SET=022 - volumes: - - /opt/qbittorrent/config:/config - - /mnt/media/downloads:/downloads - - /mnt/media/downloads/incomplete:/downloads/incomplete - ports: - - "8080:8080" - networks: [appnet] - - # Optional: Jackett for niche indexers - jackett: - image: lscr.io/linuxserver/jackett:latest - container_name: jackett - restart: unless-stopped - environment: - - PUID=1000 - - PGID=1000 - - TZ=America/New_York - - UMASK_SET=022 - volumes: - - /opt/jackett/config:/config - - /opt/jackett/torrences:/torrences - ports: - - "9117:9117" - networks: [appnet] - - # Optional: Whisparr for adult content - whisparr: - image: lscr.io/linuxserver/whisparr:latest - container_name: whisparr - restart: unless-stopped - environment: - - PUID=1000 - - PGID=1000 - - TZ=America/New_York - - UMASK_SET=022 - volumes: - - /opt/whisparr/config:/config - - /mnt/media/whisparr-movies:/whisparr-movies - - /mnt/media/downloads:/downloads - ports: - - "6969:6969" - networks: [appnet] -``` - -## Caddy Configuration - -```caddy -radarr.dankserver.local { - reverse_proxy localhost:7878 -} - -sonarr.dankserver.local { - reverse_proxy localhost:8989 -} - -lidarr.dankserver.local { - reverse_proxy localhost:8686 -} - -readarr.dankserver.local { - reverse_proxy localhost:8787 -} - -prowlarr.dankserver.local { - reverse_proxy localhost:9696 -} - -qbittorrent.dankserver.local { - reverse_proxy localhost:8080 -} - -# Optional: Jackett -jackett.dankserver.local { - reverse_proxy localhost:9117 -} - -# Optional: Whisparr -whisparr.dankserver.local { - reverse_proxy localhost:6969 -} -``` - -## Configuration Steps - -### Phase 1: Download Client - -1. Deploy qBittorrent first (or Transmission). -2. In the qBittorrent Web UI, set **No auth mode** for LAN (Settings → Web UI). -3. Create download categories: `movies`, `tv`, `music`, `books`. -4. Change the default Web UI password. - -### Phase 2: Indexer Management - -1. Deploy Prowlarr. -2. Add indexers (3–5 recommended for testing). Use the **Test** button on each. -3. Add qBittorrent as a download client in Prowlarr. -4. Verify search from the Prowlarr web UI. - -### Phase 3: Arr Apps (one at a time) - -1. Deploy Sonarr first (TV shows are the most common use case). -2. Add Prowlarr as the indexer source (Settings → Indexers → Add Prowlarr). -3. Add qBittorrent as the download client with categories. -4. Add a test series. Wait for the episode to download. Verify in `/tv/`. -5. Repeat for Radarr, Lidarr, Readarr. - -### Phase 4: Media Server Integration - -1. Configure Jellyfin libraries pointing to `/movies`, `/tv`, `/music`, `/books`. -2. Set **On Download** notifications in each arr app → Jellyfin webhook URL. -3. Test end-to-end: Add a movie in Radarr → download → verify in Jellyfin. - -## Quality Profiles - -Each arr app uses a hierarchical quality system: - -1. **Quality Profile** — Defines tiers (e.g., 2160p → 1080p BluRay → 720p). -2. **Cutoff** — The quality target. Downloads at or above cutoff are accepted. -3. **Custom Formats** — Additional filters (e.g., "Has HDR", "Is Director's Cut"). -4. **Search on Grab** — When content becomes available, all indexers are queried. - -### Radarr (Movies) - -``` -Profile: Movies 4K - Tiers: - 1. 2160p BluRay REMUX - 2. 2160p BluRay - 3. 2160p WEB-DL - 4. 1080p BluRay - 5. 1080p WEB-DL - 6. 720p - Cutoff: 1080p BluRay -``` - -### Sonarr (TV) - -``` -Profile: TV - Standard - Tiers: 2160p → 1080p → 720p - Min Size: 500 MB - Max Size: 50 GB - Cutoff: 1080p - Language Profile: English audio preferred -``` - -### Lidarr (Music) - -``` -Profile: Music - Standard - Tiers: Lossless (FLAC) → 320 kbps → 192 kbps - Cutoff: 320 kbps (or Lossless) -``` - -## Metadata Sources - -| App | Primary Source | Secondary | -|-----|---------------|-----------| -| Radarr | TMDB | TheMovieDB API | -| Sonarr | TMDB | TVDB | -| Lidarr | MusicBrainz | — | -| Readarr | Goodreads, StoryGraph | — | -| Whisparr | XH | TMDB | - -## *arr Stack vs Copyparty - -| Feature | Copyparty | *arr Stack | -|---------|-----------|------------| -| Auto-download from torrents | Basic (RSS + scripts) | Native, integrated | -| Quality profiles | No | Multi-tier, custom formats | -| Series/movie tracking | No | Watch lists, air dates | -| Manual library management | Yes | Yes, metadata-driven | -| Multi-user watchlists | No | Yes | -| Complexity | Low | Medium | -| Resource usage | Minimal | Moderate | - -Use Copyparty for curated file collections. Use *arr for automatic downloads. Use both together for maximum functionality — point *arr download directories at Copyparty's watched folders. -## Live State (as-built, verified 2026-08-29) - -Deployed shape differs from the design compose above — reality wins: - -- Mounts are the real array paths (`/mnt/entropy/downloads`, case-exact dirs - like `Movies`/`TVShows`), not `/mnt/media/*`; TZ is `America/Los_Angeles`. -- Readarr runs `lscr.io/linuxserver/readarr:amd64-1.0.980` — LSIO ships no - untagged `latest` for readarr; the tag was pinned after a manifest probe. -- Prowlarr's `/config` mount was missing mid-deploy (off-by-one in an edit); - restored in commit `67695cf`. -- **Auth posture: every arr runs `AuthenticationMethod=None` + - `AuthenticationRequired=Enabled`** — verified live via each config.xml and by - probing `/api/v3/system/status` unauthenticated (401 on all five, local and - through the vhost). Net effect: a login screen with **zero users defined**; - whoever creates the first account owns the instance. Decide the auth method - (`None` behind the Anubis wall vs `External` via authentik) *before* WAN - exposure — first-account-wins is the current race condition. -- API keys live in each `/config/config.xml` (``); they are local-only - secrets and stop being secret the moment a vhost serves the API unauthenticated. -### Chain wiring (verified live 2026-08-29) +## Chain wiring (verified live 2026-08-30) The download chain is wired and test-first verified: **indexers → Prowlarr → per-arr qBittorrent clients (category = app name) → import**. @@ -364,72 +105,46 @@ per-arr qBittorrent clients (category = app name) → import**. and hand off to their own qB download client (category routing). Mappings materialize at grab time — zero mappings right after wiring is expected, not a fault. -**Chain complete (same day):** all four arr roots live — Sonarr `/tv`, -Radarr `/movies` (201), and Lidarr `/music` + Readarr `/books` created via -API after the v1 validator layers peeled back one at a time -(`defaultQualityProfileId`/`defaultMetadataProfileId` must reference an -*existing* profile id on v1 apps; v1 has no `/api/v1/profile` endpoint — -probe endpoints by status code, empty body = absent). -**Auth-config pitfall (found same day):** all five arrs shipped with -`AuthenticationMethod=None` **plus** `AuthenticationRequired=Enabled`. On the -v1 (.NET) apps that combo is self-contradictory — UI Save is permanently -disabled and any settings save throws -`DryIoc.ScopedItemException` inside `AuthorizationMiddleware` (500 sprawl on -every page after restart). The valid representation of "no auth" in v1 is -**absence of the `` key**, not the literal string -`Disabled` — readarr's config (key absent) booted clean while its three -siblings (key=`Disabled`) 500-sprawled, which is how it was caught. Fix -applied live: key deleted on sonarr/radarr/lidarr/prowlarr, containers -restarted, all five verified serving. Posture = zero-auth arrs on LAN and -WAN; the Anubis wall guards homepage/search/hermes/prometheus/romm/files -but **not** the arrs — if WAN exposure of `/sonarr`, `/radarr` etc. is -undesired, guard them in the Anubis policy or flip auth to `External` -(needs an IdP first; auth method choice remains an operator decision). - -## Disk Layout +## Disk layout (current) ``` -/mnt/media/ -├── movies/ → Radarr root -├── tv/ → Sonarr root -├── music/ → Lidarr root -├── books/ → Readarr root -├── whisparr-movies/ → Whisparr root -├── downloads/ → qBittorrent download dir -│ ├── movies/ -│ ├── tv/ -│ ├── music/ -│ └── books/ -└── incomplete/ → qBittorrent incomplete downloads +/Volumes/COMPLETE <- completed-media volume (Mac volume) +├── sonarr-data:/config <- per-app config roots, one per unit +├── radarr-data:/config +├── lidarr-data:/config +├── readarr-data:/config +├── qbittorrent-data:/config +└── <- arr import roots live here +/Volumes/INCOMPLETE <- qB in-flight downloads (same path inside qB) ``` +qB mounts both volumes at their identical host paths +(`Volume=/Volumes/COMPLETE:/Volumes/COMPLETE`, +`Volume=/Volumes/INCOMPLETE:/Volumes/INCOMPLETE`), so a category's download path +is the same string on every container that touches it — no remapping between +download and import. + ## Gotchas -- **Timezone mismatch:** All containers should use the same TZ. Sonarr's scheduler is timezone-sensitive. -- **File permissions:** Set `umask=022` in qBittorrent. Ensure arr apps can read/move downloaded files. -- **Network conflicts:** *arr apps use many ports. Check for conflicts with existing Dankserver services. -- **Prowlarr API key rotation:** If rotated, update it in every arr app. -- **qBittorrent Web UI password:** Change default on first run. -- **Readarr stability:** Readarr is still in development. Do not rely on it for mission-critical collections. -- **Whisparr separate Jellyfin library:** Keep adult content separate from regular media. -- **RSS feed in qBittorrent:** Can auto-add torrents matching a pattern. Useful for podcast-like series. +- **Timezone:** every unit runs `TZ=America/Los_Angeles`; Sonarr's scheduler is timezone-sensitive — keep them uniform. +- **File permissions:** `UMASK_SET=022` on qBittorrent; arr apps run PUID=0 so they can read/move qB downloads. +- **Network conflicts:** *arr apps use many ports. On the machine VM, only the API ports (8989/7878/8686/8787/9696) and gluetun's published 8080 + 6881 are host-published; netns-sharers (qB) publish none of their own. +- **Prowlarr API key rotation:** If rotated, update it in every arr app (`Applications` table rows carry the real keys). +- **qBittorrent WebUI password:** generated at first boot, not a default — persist it via the PBKDF2 conf recipe in [[qBittorrent]] before any restart. +- **Readarr stability:** abandoned upstream (retired May 2026); its qB download client is parked pending a successor image. Do not rely on it for mission-critical collections. ## Best Practices 1. Use tags to route content to specific download clients or categories. 2. Enable the Blocklist in arr apps to prevent re-downloading failed torrents. 3. Set download limits in qBittorrent to avoid bandwidth saturation. -4. Back up arr configs regularly (they are small SQLite DBs + JSON). +4. Back up arr configs regularly (they are small SQLite DBs + JSON) — each lives at `/Volumes/COMPLETE/-data/config`. 5. Monitor Prowlarr indexer health — broken indexers hide new content. 6. Start with default quality profiles. Add custom formats gradually. -7. Back up arr configs: `./radarr/config`, `./sonarr/config`, etc. ## See Also -- [[Dankserver Stack]] +- [[Sonarr]] · [[Radarr]] · [[Lidarr]] · [[Readarr]] · [[Prowlarr]] · [[qBittorrent]] — per-service pages - [[Jellyfin]] — media server that consumes *arr downloads - [[Copyparty]] — alternative file viewer -- [[Calibre-Web]] — manual ebook management (Readarr auto-downloads into the same library) -- [Sonarr Wiki](https://wiki.servarr.com/sonarr) -- [Radarr Wiki](https://wiki.servarr.com/radarr) diff --git a/serverAppConfigs-docs/Dankserver/Calibre-Web.md b/serverAppConfigs-docs/Dankserver/Calibre-Web.md index 723485c..a1af441 100644 --- a/serverAppConfigs-docs/Dankserver/Calibre-Web.md +++ b/serverAppConfigs-docs/Dankserver/Calibre-Web.md @@ -2,14 +2,16 @@ Calibre-Web is a web application that browses, reads, and downloads eBooks from an existing Calibre library database. It serves as the web frontend for the Calibre e-book manager. -**Host:** Dankserver — **Hostname:** `books.dankserver.local` — **Docs:** https://github.com/linuxserver/docker-calibre-web +**Host:** Dankserver — **Access:** `books.franksdank.cloud` (unguarded Caddy +vhost — Calibre-Web serves its own login; direct proxy to +`192.168.0.235:8083`) — **Docs:** https://github.com/linuxserver/docker-calibre-web ## Facts | Item | Value | |------|-------| -| Latest version | 0.6.25-ls365 (live); 0.6.27-ls397 upstream | -| Image | `lscr.io/linuxserver/calibre-web:latest` (live: 0.6.25-ls365) | +| Running image | `lscr.io/linuxserver/calibre-web:0.6.27-ls397` — **pinned** (verified from the live quadlet unit; the pin was chosen so the cutover changed zero bits of application code) | +| Network | `pasta` (the default rootless-podman userslide network); only 8083 is host-published | | Base OS | Ubuntu Noble (24.04 LTS, since 2024-12-05) | | Port | 8083 (host) → 8083 (container) | | Default login | `admin` / `admin123` | @@ -34,7 +36,7 @@ Additional packages added: `libxfixes3` and `libasound2t64` to support epub-to-p |----------|-------|-------------| | `PUID` | `1000` | User ID | | `PGID` | `1000` | Group ID | -| `TZ` | `Etc/UTC` | Timezone | +| `TZ` | `America/Vancouver` (live unit value — not `Etc/UTC`) | | `DOCKER_MODS` | `linuxserver/mods:universal-calibre` | Optional: enables ebook conversion tools | | `OAUTHLIB_RELAX_TOKEN_SCOPE` | `1` | Required for Google OAuth | diff --git a/serverAppConfigs-docs/Dankserver/Calibre.md b/serverAppConfigs-docs/Dankserver/Calibre.md index bb11d83..143791f 100644 --- a/serverAppConfigs-docs/Dankserver/Calibre.md +++ b/serverAppConfigs-docs/Dankserver/Calibre.md @@ -25,16 +25,21 @@ Calibre 9.2.1 is the version on the live host (9.9.0 is the upstream latest). Ma ## Library Directory -| Purpose | Host path (convention) | -|---------|------------------------| -| Calibre library | `/opt/calibre-web/books` (bind-mounted to `/books` in the Calibre-Web container) | +The live Calibre-Web container bind-mounts the library at `/books`: + +| Purpose | Host path (live) | +|---------|------------------| +| Calibre library | `/home/dank/Containers/calibre-web/books` → `/books` in the Calibre-Web container | + +(The older `/opt/calibre-web/books` path was the compose-era location and is +gone; the quadlet unit mounts the Containers data root.) ## What the Container Needs - Read/write access to the library directory. Calibre-Web edits metadata through the database file. - Ownership matching `PUID=1000` / `PGID=1000` (the `dank` user on Dankserver). -## Optional: Calibre Content Server +## Optional: Calibre Content Server (not running) Calibre includes a built-in HTTP content server (`calibre-server`) that can serve the library via OPDS feeds and a mobile-friendly web interface. This enables: - OPDS feeds for mobile reading apps (FBReader, Moon+ Reader) diff --git a/serverAppConfigs-docs/Dankserver/Copyparty.md b/serverAppConfigs-docs/Dankserver/Copyparty.md index 7d59eed..9b998c7 100644 --- a/serverAppConfigs-docs/Dankserver/Copyparty.md +++ b/serverAppConfigs-docs/Dankserver/Copyparty.md @@ -2,14 +2,16 @@ Copyparty is a lightweight file server and media streamer that runs as a single Python binary. It handles large payloads, media streaming, resumable uploads, directory browsing, and WebDAV from one process. -**Host:** Dankserver — **Hostname:** `files.dankserver.local` — **Docs:** https://github.com/9001/copyparty +**Host:** Dankserver — **Access:** `files.franksdank.cloud` guarded by the +Anubis → Authentik chain ([[Caddy]] routes it post-auth to +`192.168.0.235:3923`); the published port itself stays unauthenticated on the +LAN — **Docs:** https://github.com/9001/copyparty ## Facts | Item | Value | |------|-------| -| Latest version | v1.20.21 (2026-08) | -| Image | `ghcr.io/9001/copyparty-ac:latest` (ac = full edition; the bare `copyparty:latest` tag does not exist — ghcr answers 403 on the token request for nonexistent repos) | +| Running image | `ghcr.io/9001/copyparty-ac:latest` (ac = full edition; the bare `copyparty:latest` tag does not exist — ghcr answers 403 on the token request for nonexistent repos). Version at research time (2026-08): v1.20.21 | | Port | 3923 (host) → 3923 (container) | | Volume | bind mount the shared root directory | | Auth | Per-directory `.cpy` config files, HTTP basic auth, `dirkeys`, `filekeys` | @@ -72,13 +74,12 @@ The `iv` edition is no longer available for arm32/armv6. Use `dj` for maximum co ## Volumes -Live deployment: the whole LUKS array is served at URL `/w` (the ac edition -takes its volume roots from argv plus `chdir: /w` in `/z/initcfg`, not from a -`/data` convention). Access is **read-only since 2026-08-31** (`-v /w::r:ra,dank` -— see [[#Command-line interface (ac edition)]] above). The compose bind mount is -`/mnt/entropy:/w` (host path → container path). Note the bind itself is still -rw on disk — copyparty enforces read-only at the application layer, so local -services (Jellyfin, Calibre) keep writing into the array directly. +Live deployment: the whole LUKS array is served at URL `/w` via +`Volume=/mnt/entropy:/w:ro` in the quadlet unit ([[Entropy Volume]]) — +read-only **at the mount level**, so no containerized consumer can write into +the array through this path regardless of account permissions. The ac edition +takes its volume roots from argv (`-v /w::r:ra,dank`), not from a `/data` +convention; see [[#Command-line interface (ac edition)]] above. ## Docker Compose (reference — retired 2026-09-01; live deployment is the quadlet unit below) @@ -146,13 +147,15 @@ Upgrade to v1.20.19+ to cover all known CVEs. The dirkey fix (v1.20.17) matters - **Large transfers:** Disable TLS inside the app and let Caddy terminate TLS. This avoids double encryption overhead. - **Dedicated share directory:** Do not give Copyparty the whole disk. Mount only the intended share path. - **Whole-disk share (live choice):** this deployment *does* serve the whole - 91 T array from `/w`. Since 2026-08-31 the volume is application-level - read-only for every account, so no remote write path exists. But note: + ~91 T array from `/w`. The volume is mounted `:ro` in the unit AND the + permission flags grant anonymous only `r`, so no remote write path exists at + all now. But note: **LAN-direct `:3923` is unauthenticated browse/download** (anonymous holds `r`) — Caddy + Anubis + authentik guard only `files.franksdank.cloud`, not the published port. Tighten to `-v /w::r,dank` if anonymous LAN reads become unacceptable. (Before 2026-08-31, `-v /w::A` made the array world-writable - on the LAN — see [[#Command-line interface (ac edition)]].) + on the LAN — see [[#Command-line interface (ac edition)]] — and the mount + was rw.) - **Upload tokens scoped per folder:** Prevents accidental global write access. - **CSP nonces (v1.20.17+):** Security hardening for JavaScript execution. May break third-party JS plugins (`--js-browser` / `--html-head`). - **Custom thumbnail extractors (v1.20.19+):** New `thumbex` framework. Requires configuration in `initcfg`. diff --git a/serverAppConfigs-docs/Dankserver/Dankserver Stack.md b/serverAppConfigs-docs/Dankserver/Dankserver Stack.md index affe2fa..93fc061 100644 --- a/serverAppConfigs-docs/Dankserver/Dankserver Stack.md +++ b/serverAppConfigs-docs/Dankserver/Dankserver Stack.md @@ -1,45 +1,40 @@ # Dankserver Stack -Dankserver (192.168.0.235) runs the media and library stack. Every service is reachable by hostname through the Caddy reverse proxy on the host. +Dankserver (192.168.0.235) runs the media and library stack. Public access +goes through the Caddy reverse proxy on Dankclaw; the *arr stack is exempt by +construction — it has no vhost and is reached directly by IP:port on the LAN. ```mermaid graph LR - U[User] --> C[Caddy :80/:443] - C --> R[RomM] - C --> P[Copyparty] - C --> W[Calibre-Web] - C --> J[Jellyfin] - C --> S[Sonarr] - C --> D[Radarr] - C --> L[Lidarr] - C --> A[Readarr] - C --> O[Prowlarr] - W --> L2[Calibre library] + U[User] --> C[Caddy :80/:443 on Dankclaw] + C -->|guarded: Anubis + Authentik| R[RomM :8085] + C -->|guarded| P[Copyparty :3923] + C -->|unguarded| W[Calibre-Web :8083] + C -->|unguarded| J[Jellyfin :8096] + C -->|exempt by construction| X[Plex :32400] + U -->|direct IP:port, no vhost| S[ARR stack + Prowlarr + qBittorrent on FrankBook-Pro] ``` ## Services -| Service | Hostname | Port | Docs | -|---------|----------|------|------| -| RomM | romm.dankserver.local | 8085 | [[RomM]] | -| Copyparty | files.dankserver.local | 3923 | [[Copyparty]] | -| Calibre-Web | books.dankserver.local | 8083 | [[Calibre-Web]] | -| Jellyfin | jellyfin.dankserver.local | 8096 | [[Jellyfin]] | -| Sonarr | sonarr.dankserver.local | 8989 | [[ARR-Stack]] | -| Radarr | radarr.dankserver.local | 7878 | [[ARR-Stack]] | -| Lidarr | lidarr.dankserver.local | 8686 | [[ARR-Stack]] | -| Readarr | readarr.dankserver.local | 8787 | [[ARR-Stack]] | -| Prowlarr | prowlarr.dankserver.local | 9696 | [[ARR-Stack]] | -| qBittorrent | qbittorrent.dankserver.local | 8080 | [[ARR-Stack]] | +| Service | Public route | Port | Docs | +|---------|--------------|------|------| +| RomM | `romm.franksdank.cloud` (guarded: Anubis → Authentik; post-auth route → 192.168.0.235:8085) | 8085 | [[RomM]] | +| Copyparty | `files.franksdank.cloud` (guarded; post-auth route → 192.168.0.235:3923) | 3923 | [[Copyparty]] | +| Calibre-Web | `books.franksdank.cloud` (unguarded — own login) | 8083 | [[Calibre-Web]] | +| Jellyfin | `jelly.franksdank.cloud` (unguarded — own auth) | 8096 | [[Jellyfin]] | +| Plex | `plex.franksdank.cloud` (+ legacy plain-HTTP `plex.franksdank.casa`) | 32400 | [[Plex]] | -## Optional Services +The *arr stack (Sonarr 8989, Radarr 7878, Lidarr 8686, Readarr 8787, +Prowlarr 9696) and qBittorrent (8080, behind the [[Gluetun]] tunnel netns) +run on **FrankBook-Pro**, not on this host — see [[ARR-Stack]]; none of them +have a Caddy vhost. -These services are included in the compose file but may be disabled. +## Never-deployed services -| Service | Hostname | Port | Docs | -|---------|----------|------|------| -| Jackett | jackett.dankserver.local | 9117 | [[ARR-Stack]] | -| Whisparr | whisparr.dankserver.local | 6969 | [[ARR-Stack]] | +Jackett and Whisparr were evaluated during the ARR-stack design phase and +never deployed (no unit, no vhost, no live container). Prowlarr covers the +indexer-aggregation role — see [[Prowlarr]]. ## Removed Services diff --git a/serverAppConfigs-docs/Dankserver/Jellyfin.md b/serverAppConfigs-docs/Dankserver/Jellyfin.md index 525ee9e..ff4c946 100644 --- a/serverAppConfigs-docs/Dankserver/Jellyfin.md +++ b/serverAppConfigs-docs/Dankserver/Jellyfin.md @@ -1,226 +1,68 @@ +--- +type: reference +title: Jellyfin +description: Jellyfin media server on Dankserver — quadlet unit, entropy-volume data layout, ports, client access, and hardware-transcode status. +tags: [jellyfin, dankserver, media-server] +timestamp: 2026-09-03T00:00:00Z +--- + # Jellyfin -Jellyfin is a free, open-source media server and suite of applications for organizing, managing, and streaming personal media collections (movies, TV shows, music, photos) to networked devices. It is a community fork of Emby, written in C# (.NET), and uses FFmpeg for transcoding. +Jellyfin is the free media server on Dankserver — a podman quadlet service +(`jellyfin.service`, generated from `dankserver/jellyfin/quadlet/jellyfin.container`) +serving music, movies, and shows over LAN. It replaced the earlier research +brief; it runs alongside [[Plex]], which remains the primary server for some +clients. -**Host:** Dankserver — **Hostname:** `jellyfin.dankserver.local` — **Docs:** https://jellyfin.org +**Host:** Dankserver (192.168.0.235) — **Access:** `http://192.168.0.235:8096`, +public vhost `jelly.franksdank.cloud` behind the [[Anubis]] guard chain → +[[Authentik]] outpost (post-auth route proxies `localhost:8096`). -## Facts +## Facts (verified from the live unit, 2026-09-03) | Item | Value | |------|-------| -| Latest version | Check https://jellyfin.org/downloads | -| Image | `jellyfin/jellyfin:latest` (Docker Hub) or `ghcr.io/jellyfin/jellyfin` | -| Base | Debian-based | -| Primary port | 8096 (HTTP, web UI + API) | -| HTTPS port | 8920 (optional) | -| Client discovery | 7359/udp | -| DLNA | 1900/udp (optional) | -| GPU passthrough | `/dev/dri` (Intel QSV / AMD VA-API) or NVIDIA NVENC | -| License | MIT | +| Unit | `~/.config/containers/systemd/jellyfin.container` → `jellyfin.service` (user manager), `Restart=always`, `RestartSec=5` | +| Image | `ghcr.io/jellyfin/jellyfin:latest` | +| Network | `dankserver_appnet`; publishes 8096/tcp, 8920/tcp, 7359/udp, 1900/udp | +| Data roots | `/home/dank/Containers/jellyfin/config:/config`, `/home/dank/Containers/jellyfin/cache:/cache` | +| Media | `Volume=/mnt/entropy:/data:ro` — the whole [[Entropy Volume]] mounted read-only; nothing automated writes to it | +| GPU | none — no `AddDevice`; CPU decode only (jellyfin-ffmpeg path) | +| Env quirks | `DOTNET_SYSTEM_IO_DISABLEFILELOCKING=true`, `LD_PRELOAD=libjemalloc.so.2`, `MALLOC_TRIM_THRESHOLD_=131072` kept verbatim from the compose-era container (zero-drift cutover) | +| Health | `curl -f http://localhost:8096/health` every 30 s | -## Architecture +## Data layout -```mermaid -graph LR - U[User] --> C[Caddy :80/:443] - C --> J[Jellyfin :8096] - J --> Lib[/media/movies] - J --> Lib2[/media/shows] - J --> Lib3[/media/music] - J --> Conf[Jellyfin config] - J --> Cache[Jellyfin cache] +``` +/home/dank/Containers/jellyfin/config -> /config (JELLYFIN_DATA_DIR) +/home/dank/Containers/jellyfin/cache -> /cache (JELLYFIN_CACHE_DIR, XDG_CACHE_HOME) +/mnt/entropy -> /data (read-only media volume) ``` -## Docker Compose (reference — retired 2026-09-01; live mounts use `/home/dank/Containers/jellyfin`, see Deployment below) +Library folders point at `/data` paths; because the mount uses the same +absolute path as on the host, library paths survive container recreation. -```yaml -services: - jellyfin: - image: jellyfin/jellyfin:latest - container_name: jellyfin - restart: unless-stopped - user: "1000:1000" - ports: - - "8096:8096/tcp" - - "8920:8920/tcp" - - "7359:7359/udp" - - "1900:1900/udp" - environment: - - JELLYFIN_PublishedServerUrl=http://192.168.0.235:8096 - - DOTNET_SYSTEM_IO_DISABLEFILELOCKING=true - volumes: - - /opt/jellyfin/config:/config - - /opt/jellyfin/cache:/cache - - /mnt/media/movies:/data/movies:ro - - /mnt/media/shows:/data/shows:ro - devices: - - /dev/dri:/dev/dri - group_add: - - "992" # Host render group GID — verify with `getent group render` - healthcheck: - test: ["CMD", "curl", "-f", "http://localhost:8096/health"] - interval: 30s - timeout: 10s - retries: 3 -``` +## Ports & access -## Caddy Configuration +| Port | Proto | Purpose | +|------|-------|---------| +| 8096 | TCP | Web UI + API (`JELLYFIN_PublishedServerUrl=http://192.168.0.235:8096`) | +| 8920 | TCP | DLNA/UPnP root device control | +| 7359 | UDP | service discovery (client auto-discovery) | +| 1900 | UDP | SSDP discovery | -```caddy -jellyfin.dankserver.local { - reverse_proxy 127.0.0.1:8096 +Client access paths and the public-exposure policy (auth wall required before +any public vhost; Plex-style claim tokens do not exist here — Jellyfin uses its +own users/API keys) follow the fleet [[Authentik]]/[[Anubis]] chain pattern. - transport http { - versions h2c 1.1 - } -} -``` +## Configuration workflow -Set **Base URL** to `/` (or the path you configure) in Jellyfin Dashboard → Networking. Add `127.0.0.1` to **Known Proxies**. - -## Storage - -| Mount | Purpose | Size Estimate | -|-------|---------|---------------| -| `/home/dank/Containers/jellyfin/config` | SQLite database, settings, cached images | 10–100 GB | -| `/home/dank/Containers/jellyfin/cache` | Transcoding segments, extracted posters | Self-cleaning per session | -| `/mnt/entropy/Movies`, `/mnt/entropy/TVShows` | Media, **read-only binds** (`:ro`) — no automated write path | — | - -The database must be on local storage (SSD/NVMe preferred). Media libraries can be on NFS/mergerfs. If media is on NFS, set `DOTNET_SYSTEM_IO_DISABLEFILELOCKING=true`. - -## Deployment (Quadlet) - -Since 2026-09-01: `dankserver/jellyfin/quadlet/jellyfin.container` → -`jellyfin.service` (generator-enabled), deployed with -`./scripts/deploy.sh dankserver --service jellyfin`. GPU passthrough uses -`AddDevice=/dev/dri` — plain `Device=` is **not** a quadlet key and makes the -v1 generator reject the whole unit (learned live: "unsupported key 'Device' -in group 'Container'"). Entropy mounts stay `:ro`; the container runs as -root inside the user namespace, so the render-node ACLs apply via the device -cgroup regardless of `GroupAdd=keep-groups`. - -## Authentication - -- **Built-in auth:** per-user libraries, parental controls, max bitrate - limits. The local `dank` admin account is built-in; its password is - Frank's bootstrap value — never recorded in this repo. (2026-09-01: a - corrupted session-archive reading briefly suggested the password had - changed; verified offline against the stored PBKDF2-SHA512 hash, the - bootstrap value still authenticates.) -- **LDAP via Authentik (live 2026-09-01):** the LDAP-Auth plugin - authenticates users against the authentik LDAP outpost on Dankclaw — see - [[Authentik]] for the outpost unit, provider, and RBAC objects. - -### LDAP-Auth plugin (v23.0.0.0, live 2026-09-01) - -- **Install from the GitHub releases zip** — `repo.jellyfin.org`'s stable - manifest path 404s here, so fetch - `jellyfin/jellyfin-plugin-ldapauth` release asset - `ldap-authentication_23.0.0.0.zip` from GitHub and unzip into - `config/plugins/LDAP-Auth_23.0.0.0/`. The config lives at - `config/plugins/configurations/LDAP-Auth.xml` — write it directly, then - restart the service. -- **Live config:** server `192.168.0.143:389`, base DN - `dc=franksdank,dc=cloud`, bind DN - `cn=svc-jellyfin-ldap,ou=users,dc=franksdank,dc=cloud`, bind password = - the authentik outpost token (secret — the XML lives on the host only, - never in the repo), search filter - `(memberOf=cn=jellyfin_users,ou=groups,dc=franksdank,dc=cloud)`, admin - filter on `cn=jellyfin_admins,ou=groups,…`, `CreateUsersFromLdap=true` - (auto-create on first login). -- **Attribute separator is a comma.** `LdapSearchAttributes` is - `Split(',')` in the plugin source — a semicolon-separated list - (`uid;cn;mail;displayName`) parses as ONE bogus attribute, the search - silently matches nothing, and the log says `Found no users matching X`. - Use `uid,cn,mail,displayName`. -- **Username attribute is `cn`.** Authentik 2026.x maps `uid` to an opaque - per-user hash, not the username, so `uid=` never matches. Set - `LdapUsernameAttribute=cn` (authentik exposes the username as `cn`). -- **Verify with a throwaway user:** create a test member of - `jellyfin_users` in authentik, then - `POST /Users/AuthenticateByName` with headers `Content-Type: - application/json` **and** `X-Emby-Authorization: MediaBrowser - Client="…", Device="…", DeviceId="…", Version="10.11.0"` — both are - required in 10.11 (missing `X-Emby-Authorization` → 400). 200 + non-admin - policy = LDAP path works. Delete the test user from authentik **and** - Jellyfin afterward. -- **Plugin load lines only show in `journalctl --user -u jellyfin.service`** - (`Loaded plugin: LDAP-Auth 23.0.0.0`) — `podman logs` does not carry the - loader lines in this image. - -## Metadata Scraping - -| Provider | Content | Type | -|----------|---------|------| -| TheMovieDb (TMDb) | Movies, TV shows, posters, fan art, overviews | Default | -| OMDb API | Movies only, English metadata | Default | -| TheTVDB | TV shows, episodes | Plugin | -| fanart.tv | Extra artwork, banners, thumbnails | Plugin | -| AniDB | Anime metadata | Plugin | -| MusicBrainz | Music metadata | Plugin | -| Open Subtitles | Subtitle downloads | Plugin | -| Intro Skipper | TV show intro detection | Plugin | - -## Clients - -| Platform | App | Quality | -|----------|-----|---------| -| Web | Jellyfin Web | Excellent | -| Android | Jellyfin (Google Play / F-Droid) | Excellent | -| Android TV / Fire TV | Jellyfin | Good | -| iOS / iPadOS | Swiftfin (third-party) | Good | -| Desktop | Jellyfin Media Player (mpv-based) | Excellent | -| Roku | Jellyfin (Channel Store) | Good | -| Kodi | Jellyfin addon | Excellent | -| Samsung/LG Smart TVs | TV browser | Fair | - -## Jellyfin vs Plex - -| Feature | Jellyfin | Plex | -|---------|----------|------| -| Cost | Free, no tiers | Free core; Plex Pass ($5/mo or $120 lifetime) | -| License | MIT | Proprietary | -| Account required | No | Yes | -| Hardware transcoding | Free | Plex Pass required | -| Mobile sync | Free | Plex Pass | -| Live TV / DVR | Free | Plex Pass | -| Client apps | Good, improving | Excellent, widest device support | - -Run Jellyfin alongside Plex for an incremental migration. Point Jellyfin at the same media folders as Plex. Watch history and metadata will not transfer cleanly. - -## Resource Requirements - -- **Idle / Direct Play:** ~200–500 MB RAM, <5% CPU. Negligible. -- **1080p transcode (CPU):** 40–60% CPU on a modern multi-core CPU. -- **1080p transcode (with QSV):** 3–5% CPU. -- **4K HDR transcode (with QSV):** 5–15% CPU. -- **Minimum host RAM:** 4 GB. 8 GB comfortable for transcoding. - -## Deployment Checklist - -1. Verify GPU on host: `ls -l /dev/dri/`, `lspci | grep -i vga`, `getent group render`. -2. Install media drivers: `sudo apt install intel-media-va-driver-non-free vainfo intel-gpu-tools`. -3. Create directories: `/home/dank/Containers/jellyfin/config`, `/home/dank/Containers/jellyfin/cache`. -4. Write compose file, verify device and GID. -5. Deploy: `podman compose up -d`. -6. Test GPU passthrough: `podman exec jellyfin /usr/lib/jellyfin-ffmpeg/vainfo --display drm --device /dev/dri/renderD128`. -7. Configure Caddy reverse proxy. Set Known Proxies in Jellyfin. -8. Add media libraries in Dashboard. -9. Install plugins: Open Subtitles, fanart.tv, Intro Skipper. -10. Test playback on Android/Chrome. - -## Gotchas - -- **GPU passthrough silently failing:** `/dev/dri` must be passed and the correct render node used. Verify with `vainfo` inside the container. -- **Wrong render group GID:** Common GID is 992, but varies per host. Run `getent group render` to find it. -- **Subtitle burn-in triggers full transcode:** PGS (image-based) subtitles force full video transcoding. SRT/ASS (text-based) play fine. -- **Database on NFS:** SQLite on network storage causes slow startup and corruption risk. Keep `/config` on local storage. -- **Client bitrate limit too low:** Many clients default to 20 Mbps. Set Max Streaming Bitrate to Original or Maximum. -- **Naming convention mismatches:** Non-standard folder/file names cause missing metadata. Use `Movie Title (Year)` for movies and `Show Name/Season 01/Show Name S01E01.mkv` for TV. +1. Create libraries pointing at `/data` folders (movies, shows, audio). +2. Set metadata/language preferences (`LANG=en_US.UTF-8` pinned in the unit). +3. Configure clients to use `http://192.168.0.235:8096` or the guarded vhost. ## See Also -- [[Dankserver Stack]] -- [[ARR-Stack]] — automated download into Jellyfin libraries -- [[Copyparty]] — alternative file viewer for existing collections -- Plex — existing media server on this host +- [[Plex]] — co-resident media server on the same volume +- [[Entropy Volume]] — the 91 T array mounted read-only at `/data` +- [[Caddy]] · [[Anubis]] · [[Authentik]] — edge chain for `jelly.franksdank.cloud` diff --git a/serverAppConfigs-docs/Dankserver/Plex.md b/serverAppConfigs-docs/Dankserver/Plex.md index b7b3e24..d825921 100644 --- a/serverAppConfigs-docs/Dankserver/Plex.md +++ b/serverAppConfigs-docs/Dankserver/Plex.md @@ -1,10 +1,10 @@ # Plex -Plex Media Server is the **containerized media server on Dankserver**: a -podman quadlet (`plex.service`) under the systemd **user** generator, -generated from `dankserver/plex/quadlet/plex.container`. It is the only media -server actually listening on this host. Jellyfin, by contrast, is a research -brief on this host, not a running service (see [[Jellyfin]]). +Plex Media Server is a **containerized media server on Dankserver**: a podman +quadlet (`plex.service`) under the systemd **user** generator, generated from +`dankserver/plex/quadlet/plex.container`. It shares the host with a second live +media server, [[Jellyfin]] (`jellyfin.service`, listening on 8096); both serve +from the same read-only Entropy Volume mount. **Host:** Dankserver — **Ports:** 32400/tcp (PMS web + API), 32400 is the only port PMS needs for client streaming; LAN clients connect directly, @@ -21,7 +21,7 @@ public traffic can be fronted by Caddy like every other vhost. | Identity | fleet rootless model — container root maps to the `dank` user (1000:1000); the deployer chowns the data root on first cutover | | Port | `32400/tcp` published on `0.0.0.0` — zero client reconfiguration | | Network | `dankserver_appnet`, alias `plex`; Tautulli reaches it at `http://plex:32400` | -| GPU | none by decision — CPU decode only; the RTX 3090 stays dedicated to `frank-default-small` | +| GPU | none by decision — CPU decode only; the RTX 3090 stays dedicated to `frank-small` | | Deploy | `./scripts/deploy.sh dankserver --service plex` | | Docs | https://support.plex.tv | diff --git a/serverAppConfigs-docs/Dankserver/RomM.md b/serverAppConfigs-docs/Dankserver/RomM.md index 6dedd3c..efd0bc3 100644 --- a/serverAppConfigs-docs/Dankserver/RomM.md +++ b/serverAppConfigs-docs/Dankserver/RomM.md @@ -2,14 +2,15 @@ RomM (ROM Manager) is a self-hosted ROM library manager and player. It scans a ROM collection, enriches it with metadata and cover art from multiple providers, and serves it through a clean web interface. RomM also supports browser-based emulation via EmulatorJS and native emulator streaming. -**Host:** Dankserver — **Hostname:** `romm.dankserver.local` — **Docs:** https://docs.romm.app +**Host:** Dankserver — **Access:** `romm.franksdank.cloud` guarded by the +Anubis → Authentik chain ([[Caddy]] routes it post-auth to +`192.168.0.235:8085`) — **Docs:** https://docs.romm.app ## Facts | Item | Value | |------|-------| -| Latest version | 5.2.0 (released 2026-07-29) | -| Image | `ghcr.io/rommapp/romm:latest` | +| Running image | `ghcr.io/rommapp/romm:latest` (rolling tag — no pin; the version claims on this page were true at research time; verify against the live container before relying on them) | | Port | 8085 (host) → 8080 (container) | | Database | MariaDB (default); PostgreSQL optional | | Cache / Queue | Redis or Valkey (required for task queue) | @@ -21,7 +22,9 @@ RomM (ROM Manager) is a self-hosted ROM library manager and player. It scans a R ## Architecture -RomM 5.2.0 requires three supporting services. The compose stack includes `romm`, `mariadb`, and `redis` (or `valkey`). +Current RomM releases require MariaDB plus Redis (or Valkey) for the task +queue; this deployment runs **redis** (`REDIS_HOST=redis` in the live unit), +not valkey. ```mermaid graph LR @@ -68,7 +71,7 @@ These are set via environment variables or in `config.yml`: | `MOBYGAMES_API_KEY` | MobyGames | Paid hobbyist API. Note: RomM recommends Screenscraper as free alternative. | | `RETROACHIEVEMENTS_API_KEY` | RetroAchievements | Hash-based achievements via bundled RAHasher binary. | | `STEAMGRIDDB_API_KEY` | SteamGridDB | Custom cover art via the search cover button. | -| `HASHEOUS_API_ENABLED` | Hasheous | Set to `true`. Free, hash-based, proxies IGDB data. Fast scans. | +| `HASHEOUS_API_ENABLED` | Hasheous | Set to `true` in the live unit env file. Free, hash-based, proxies IGDB data. Fast scans. | | `PLAYMATCH_API_ENABLED` | Playmatch | Set to `true`. Multi-provider hash matching (IGDB, SS, SteamGridDB, RA). | ### Config File @@ -117,15 +120,15 @@ Since 2026-09-01 the trio runs as repo-tracked quadlet units, deployed with ## Volumes +The live unit mounts one root bind — `Volume=/home/dank/Containers/romm:/romm` +— so `/romm/config`, `/romm/library`, `/romm/resources`, and `/romm/assets` +all resolve inside a single host-side data root: + | Container path | Host path | |----------------|-----------| -| `/romm/library` | `/home/dank/Containers/romm/library` | -| `/romm/resources` | `/home/dank/Containers/romm/resources` | -| `/romm/config` | `/home/dank/Containers/romm/config` | -| `/var/lib/mysql` | `/home/dank/Containers/romm/mariadb` (mapped subuid owner — never chown) | -| `/data` (redis) | `/home/dank/Containers/romm/redis` (mapped subuid owner) | - -The library volume contains ROM files and subdirectories per platform. The resources volume stores cached artwork, metadata, and the asset cache. The config volume holds `config.yml` and other configuration. +| `/romm/*` (single root bind) | `/home/dank/Containers/romm/*` | +| `/var/lib/mysql` (romm-mariadb) | `/home/dank/Containers/romm/mariadb` (mapped subuid owner — never chown) | +| `/data` (romm-redis) | `/home/dank/Containers/romm/redis` (mapped subuid owner) | The cutover rescued RomM's anonymous `/romm` volume (assets, plus empty mountpoint stubs that shadowed nothing) into the data root before first unit diff --git a/serverAppConfigs-docs/Dankserver/lidarr.md b/serverAppConfigs-docs/Dankserver/lidarr.md index 607224c..630c57c 100644 --- a/serverAppConfigs-docs/Dankserver/lidarr.md +++ b/serverAppConfigs-docs/Dankserver/lidarr.md @@ -1,8 +1,19 @@ +--- +type: reference +title: Lidarr +description: Lidarr music manager in the *arr stack on FrankBook-Pro — live quadlet deployment, ports, volumes, and wiring facts. +tags: [lidarr, arr-stack, frankbook-pro] +timestamp: 2026-09-03T00:00:00Z +--- + # Lidarr -Lidarr manages music albums in the *arr stack on Dankserver. It automatically searches, downloads, and organizes albums from indexers into the Jellyfin music library. +Lidarr manages music albums in the *arr stack. The stack runs on +**FrankBook-Pro** (the Mac mini) as quadlet units inside its podman machine — +not on Dankserver. It searches, downloads, and organizes albums from indexers +into the Jellyfin music library. -**Host:** Dankserver — **Hostname:** `lidarr.dankserver.local` — **Docs:** https://wiki.servarr.com/lidarr +**Host:** FrankBook-Pro (podman machine) — **Access:** direct port `8686` (no reverse-proxy vhost; the *arr stack is exempt by construction from the Anubis guard chain) — **Docs:** https://wiki.servarr.com/lidarr ## Facts @@ -10,36 +21,41 @@ Lidarr manages music albums in the *arr stack on Dankserver. It automatically se |------|-------| | Image | `lscr.io/linuxserver/lidarr:latest` | | Port | 8686 (host) → 8686 (container) | +| Env | `PUID=0`, `PGID=0`, `TZ=America/Los_Angeles`, `UMASK_SET=022` | +| Config root | `/Volumes/COMPLETE/lidarr-data:/config` | | Min RAM | 256 MB | | Metadata | MusicBrainz | -## Docker Compose +## Deployment (current) -```yaml -lidarr: - image: lscr.io/linuxserver/lidarr:latest - container_name: lidarr - restart: unless-stopped - environment: - - PUID=1000 - - PGID=1000 - - TZ=America/New_York - - UMASK_SET=022 - volumes: - - /opt/lidarr/config:/config - - /mnt/media/music:/music - - /mnt/media/downloads:/downloads - ports: - - "8686:8686" - networks: [appnet] +Quadlet unit `lidarr.container` from this repo (`frankbook-pro/lidarr/quadlet/`) +is installed inside the podman machine at +`/home/core/.config/containers/systemd/lidarr.service` by the frankbook-pro +handler in `scripts/deploy-remote.sh`. Unit shape: + +```ini +[Container] +ContainerName=lidarr +Image=lscr.io/linuxserver/lidarr:latest +Environment=PUID=0 +Environment=PGID=0 +Environment=TZ=America/Los_Angeles +Environment=UMASK_SET=022 +Volume=/Volumes/COMPLETE/lidarr-data:/config +PublishPort=8686:8686 + +[Service] +TimeoutStartSec=900 +Restart=always ``` ## Configuration -1. Add Prowlarr as the indexer source (prefer torrent-based indexers for FLAC). -2. Add qBittorrent as the download client with the `music` category. +1. Add Prowlarr as the indexer source (prefer torrent-based indexers for FLAC — + the Nyaa feed carries music categories; see [[Prowlarr]]). +2. Add qBittorrent as the download client with the `music` category ([[qBittorrent]]). 3. Set quality profile (Lossless → High Bitrate → Standard). -4. Set root folder to `/music`. +4. Set the root folder to the music root under the COMPLETE volume. 5. Add artists and verify downloads. ## Gotchas diff --git a/serverAppConfigs-docs/Dankserver/mariadb.md b/serverAppConfigs-docs/Dankserver/mariadb.md index d6134db..0776c72 100644 --- a/serverAppConfigs-docs/Dankserver/mariadb.md +++ b/serverAppConfigs-docs/Dankserver/mariadb.md @@ -1,47 +1,82 @@ +--- +type: reference +title: MariaDB (RomM Backend) +description: MariaDB 11 database backend for RomM on Dankserver — quadlet unit, network alias, env-file secret handling, and backup path. +tags: [mariadb, romm, dankserver] +timestamp: 2026-09-03T00:00:00Z +--- + # MariaDB (RomM Backend) -MariaDB 11 provides the database backend for RomM on Dankserver. RomM 5.2.0 requires MariaDB (or PostgreSQL) for its data store. +MariaDB 11 provides the database backend for [[RomM]] on Dankserver. RomM's +current release requires MariaDB (or PostgreSQL) for its data store; this +deployment uses MariaDB. -**Host:** Dankserver — **Docs:** https://mariadb.com/kb/en/docker-mariadb-information/ +**Host:** Dankserver — container name `romm-mariadb`, unit +`romm-mariadb.service` (user-manager quadlet from +`dankserver/romm/quadlet/romm-mariadb.container`). -## Facts +## Facts (verified from the live unit) | Item | Value | |------|-------| -| Image | `docker.io/mariadb:11` | -| Port | 3306 (internal, within `appnet`) | -| Database name | `romm` | -| Data volume | `/opt/romm/mariadb` | +| Image | `docker.io/library/mariadb:11` | +| Port | 3306 — internal only; the unit publishes **no** port, so the DB is unreachable from the host network by construction | +| Network | `dankserver_appnet` with `alias=mariadb` — RomM reaches it via `DB_HOST=mariadb` | +| Database / user | `romm` / `romm` | +| Data volume | `/home/dank/Containers/romm/mariadb:/var/lib/mysql` | +| Secrets | supplied via `EnvironmentFile=/home/dank/Containers/romm/env` (mode 0600, host-local — `MARIADB_ROOT_PASSWORD` and friends never enter the repo) | -## Docker Compose +## Unit shape (as deployed) -```yaml -mariadb: - image: docker.io/mariadb:11 - container_name: romm-mariadb - restart: unless-stopped - environment: - MARIADB_ROOT_PASSWORD: "${MARIADB_ROOT_PASSWORD}" - MARIADB_DATABASE: romm - MARIADB_USER: "${ROMM_DB_USER}" - MARIADB_PASSWORD: "${ROMM_DB_PASSWD}" - volumes: - - /opt/romm/mariadb:/var/lib/mysql - healthcheck: - test: ["CMD", "mariadb-admin", "ping", "-h", "localhost"] - interval: 10s - timeout: 5s - retries: 3 +```ini +[Unit] +Description=RomM mariadb container +After=network.target +Wants=romm-redis.service + +[Container] +ContainerName=romm-mariadb +Image=docker.io/library/mariadb:11 +Network=dankserver_appnet:alias=mariadb +EnvironmentFile=/home/dank/Containers/romm/env +Environment=MARIADB_DATABASE=romm +Environment=MARIADB_USER=romm +Volume=/home/dank/Containers/romm/mariadb:/var/lib/mysql +HealthCmd=mariadb-admin ping -h localhost +HealthInterval=30s +HealthTimeout=10s +HealthRetries=3 + +[Service] +Restart=always +RestartSec=5 ``` +`MARIADB_ROOT_PASSWORD` and `MARIADB_PASSWORD` are read from the env file at +container-create time (`EnvironmentFile=` appears in both `[Container]` and +`[Service]` so `podman generate systemd`-style regeneration keeps them). The +root password is a real secret — per repo secret rules it lives only in the +host-local env file, never in git. + +## Boot order + +RomM declares `Wants=romm-mariadb.service` + `After=romm-mariadb.service`, so +a cold boot starts the database first; the health ping (`mariadb-admin ping`) +is what marks the unit healthy for anything gating on it. + ## Backup -Back up the volume directory periodically: +Back up the volume directory periodically (stop-free: rsync of a quiet DB dir): ```bash -sudo rsync -a /opt/romm/mariadb /mnt/backup/romm-mariadb/ +sudo rsync -a /home/dank/Containers/romm/mariadb /mnt/backup/romm-mariadb/ ``` +For consistency-critical dumps prefer `mariadb-dump` over file copy; the data +dir copy is only safe while RomM traffic is idle. + ## See Also - [[RomM]] — service that uses this database +- [[redis]] — the sibling cache/queue container on the same network diff --git a/serverAppConfigs-docs/Dankserver/prowlarr.md b/serverAppConfigs-docs/Dankserver/prowlarr.md index a32f861..a79e79c 100644 --- a/serverAppConfigs-docs/Dankserver/prowlarr.md +++ b/serverAppConfigs-docs/Dankserver/prowlarr.md @@ -1,20 +1,55 @@ +--- +type: reference +title: Prowlarr +description: Prowlarr indexer-management layer for the *arr stack on FrankBook-Pro — feed routes, sync model, API surface, and verified live gotchas. +tags: [prowlarr, arr-stack, frankbook-pro] +timestamp: 2026-09-03T00:00:00Z +--- + # Prowlarr Prowlarr is the indexer management layer for the *arr stack. It hosts the indexer definitions and exposes them as Torznab feeds and downloads; Sonarr, Radarr, Lidarr, and Readarr query those feeds and receive results. -**Host:** Dankserver — **Hostname:** `prowlarr.dankserver.local` — **Docs:** https://wiki.servarr.com/prowlarr +**Host:** FrankBook-Pro (podman machine) — **Access:** direct port `9696` (no +reverse-proxy vhost; the *arr stack is exempt by construction from the Anubis +guard chain) — **Docs:** https://wiki.servarr.com/prowlarr ## Facts | Item | Value | |------|-------| -| Image | `lscr.io/linuxserver/prowlarr:latest` | +| Image | `lscr.io/linuxserver/prowlarr:latest` (runs v2.5.2 line) | | Port | 9696 (host) → 9696 (container) | +| Env | `PUID=0`, `PGID=0`, `TZ=America/Los_Angeles`, `UMASK_SET=022` | +| Config root | `/Volumes/COMPLETE/prowlarr-data:/config` | | Min RAM | 256 MB | | Auth | Forms (web UI) + API key (`/api/v1/...` and feed routes) | +## Deployment (current) + +Quadlet unit `prowlarr.container` from this repo +(`frankbook-pro/prowlarr/quadlet/`), installed inside the podman machine at +`/home/core/.config/containers/systemd/prowlarr.service` by the frankbook-pro +handler in `scripts/deploy-remote.sh`: + +```ini +[Container] +ContainerName=prowlarr +Image=lscr.io/linuxserver/prowlarr:latest +Environment=PUID=0 +Environment=PGID=0 +Environment=TZ=America/Los_Angeles +Environment=UMASK_SET=022 +Volume=/Volumes/COMPLETE/prowlarr-data:/config +PublishPort=9696:9696 + +[Service] +TimeoutStartSec=900 +Restart=always +``` + ## Live wiring (verified end-to-end 2026-08-30) Indexer queries flow **through** Prowlarr; a grab hands off to the querying @@ -35,35 +70,17 @@ http://prowlarr:9696/{indexerId}/download?link=...&file=... (torrent handoff) The global API key is in `config.xml` (``); per-application keys are only used by Prowlarr's own sync calls, NOT by the feeds. The arr download clients authenticate to qBittorrent with the permanent WebUI password stored -in `/home/dank/.qbpass` (mode 600) on Dankserver. +in `/home/dank/.qbpass` (mode 600, owner `dank`) on Dankserver — see +[[qBittorrent]] for why that password must be pinned in the conf file. -**Readarr caveat:** Readarr is abandoned upstream (last release 0.4.x); its -qBittorrent client cannot authenticate against qB 5 (`Authentication -failure` on the connection test while Sonarr/Lidarr/Radarr pass with the -same credentials). The books pipeline is parked pending a Readarr successor; -the indexer row itself is healthy. +**Readarr caveat:** Readarr is abandoned upstream; its qBittorrent client +cannot authenticate against newer qB Web-API versions (`Authentication +failure` on the connection test while Sonarr/Lidarr/Radarr pass with the same +credentials — root cause: qB ≥ 5's 204 empty-body login success, fixed fleet- +wide by pinning qB to 4.6.7). The books pipeline is parked pending a Readarr +successor; the indexer row itself is healthy. -## Docker Compose - -```yaml -prowlarr: - image: lscr.io/linuxserver/prowlarr:latest - container_name: prowlarr - restart: unless-stopped - environment: - - PUID=1000 - - PGID=1000 - - TZ=America/New_York - - UMASK_SET=022 - volumes: - - /opt/prowlarr/config:/config - - /mnt/media/downloads:/downloads:ro - ports: - - "9696:9696" - networks: [appnet] -``` - -## Gotchas (all verified live 2026-08-30) +## Gotchas (verified live 2026-08-30) - **The feed route is `/{indexerId}/api`.** There is no `/torznab/{id}/feed` — that path (and any other unmatched path) hits the Forms-auth catch-all @@ -92,12 +109,13 @@ prowlarr: - Instance name/`InstanceName=Prowlarr` in `config.xml` does NOT prefix the API/feed routes on this build (they answer at root; the `/Prowlarr/...` prefix 302s to the SPA). -- **Application auto-sync cannot manage these rows** (they carry - `SyncLevel=2`): `POST /api/v1/applications/test` fails with - `Unable to cast object of type 'NzbDrone.Core.Thing…'` — Prowlarr v1 - cannot deserialize Radarr 6.3's newer response types. The manual Torznab - rows above are therefore the real integration; sync neither duplicates - nor clobbers them. +- **Application auto-sync model (v2):** Applications are first-class rows in + the `Applications` table; each of the four app rows (sonarr/radarr/lidarr/ + readarr) carries the real baseUrl+apiKey with `SyncLevel=FullSync`. The + earlier v1-era failure where `POST /api/v1/applications/test` threw + `Unable to cast object of type 'NzbDrone.Core.Thing…'` (v1 could not + deserialize Radarr 6.3's newer response types) is historical — it was the + reason the manual Torznab rows were created in the first place. - Prowlarr runs `AuthenticationMethod=Forms` + `AuthenticationRequired=Enabled` healthily — the DryIoc crash combo was `None`+`Enabled` only (see [[radarr]] auth notes). @@ -105,7 +123,4 @@ prowlarr: ## See Also - [[ARR-Stack]] — full *arr stack documentation -- [[radarr]] -- [[sonarr]] -- [[lidarr]] -- [[readarr]] +- [[Radarr]] · [[Sonarr]] · [[Lidarr]] · [[Readarr]] · [[qBittorrent]] diff --git a/serverAppConfigs-docs/Dankserver/qbittorrent.md b/serverAppConfigs-docs/Dankserver/qbittorrent.md index 2866aa9..78eefd5 100644 --- a/serverAppConfigs-docs/Dankserver/qbittorrent.md +++ b/serverAppConfigs-docs/Dankserver/qbittorrent.md @@ -1,27 +1,44 @@ +--- +type: reference +title: qBittorrent +description: qBittorrent download client for the *arr stack — pinned 4.6.7 on FrankBook-Pro, shares the Gluetun WireGuard netns, PBKDF2 WebUI credential recipe. +tags: [qbittorrent, arr-stack, frankbook-pro, gluetun] +timestamp: 2026-09-03T00:00:00Z +--- + # qBittorrent -qBittorrent is the torrent download client for the *arr stack on Dankserver. It receives download requests from Sonarr, Radarr, Lidarr, and Readarr via category tagging. +qBittorrent is the torrent download client for the *arr stack. The stack runs on +**FrankBook-Pro** (the Mac mini) as quadlet units inside its podman machine — +not on Dankserver. It receives download requests from Sonarr, Radarr, Lidarr, +and Readarr via category tagging. -**Host:** Dankserver — **Hostname:** `qbittorrent.dankserver.local` — **Docs:** https://www.qbittorrent.org +**Host:** FrankBook-Pro (podman machine) — **Access:** WebUI on port `8080`, +published by the [[Gluetun]] unit because qBittorrent shares that container's +network namespace (a netns-sharer publishes no ports of its own). ## Facts | Item | Value | |------|-------| -| Image | `lscr.io/linuxserver/qbittorrent:latest` | -| Port | 8080 (host) → 8080 (container) | -| Min RAM | 512 MB | -| Auth | Web UI username/password; LAN mode available | +| Image | `lscr.io/linuxserver/qbittorrent:4.6.7` — **pinned**, see the pin rationale below | +| Network | `Network=gluetun.container` (torrent egress exits via the WireGuard/ProtonVPN tunnel) | +| Ports | 8080 (WebUI) and 6881 TCP+UDP published on the gluetun unit | +| Env | `PUID=0`, `PGID=0`, `TZ=America/Los_Angeles`, `UMASK_SET=022` | +| Volumes | `/Volumes/COMPLETE/qbittorrent-data:/config`, plus `/Volumes/COMPLETE` and `/Volumes/INCOMPLETE` mounted at identical paths | +| Auth | Web UI username/password (`admin` + generated password); LAN bypass not used | -## Configuration +## Why the 4.6.7 pin exists (2026-09-01) -1. Keep Web UI authentication ON (LAN bypass not needed — the arr apps - authenticate with the API) and give them a permanent password. -2. Create download categories per app (`radarr`, `sonarr`, `lidarr`, - `readarr`): the arr download clients route category-per-app, and Prowlarr - feeds hand grabs to each app's own client. -3. Set max active downloads: Settings → Downloads (recommended: 5 global, - 3 per category). +Readarr's abandoned qBittorrent client rejects qB ≥ 5's **204 empty-body login +success** as `Authentication failure` — a runtime break, not just an API-create +issue. The fleet pins `lscr.io/linuxserver/qbittorrent:4.6.7` while Readarr is +in the stack. **Never unpin to `latest` while Readarr is in the fleet.** + +Second trap on any version flip: qB 5.x's shutdown conf rewrite leaves a +`WebUI\Password_PBKDF2=@ByteArray(...)` line that 4.6.7 rejects — every login +then returns "invalid credentials" (the arrs included). Fix = rewrite the same +conf line with the same password while qB is stopped. ## Persistent WebUI credentials (verified 2026-08-30) @@ -46,31 +63,34 @@ val = (base64.b64encode(salt) + b":" + base64.b64encode(h)).decode() Then `podman start qbittorrent` and confirm login survives a `podman restart` — the temp-password rotation stops the moment stored -credentials verify. The chosen value lives host-local in -`/home/dank/.qbpass` (mode 600, owner `dank`) — never in git; every arr -download client and `prowlarr.md` reference it. (The classic -`@ByteArray(salt+hash)` form is WRONG for qb5: login 401s on it; verify() -base64-decodes the two halves separately.) +credentials verify. The chosen value lives host-local in `/home/dank/.qbpass` +(mode 600, owner `dank`) — never in git; every arr download client and +[[Prowlarr]] reference it. (The classic `@ByteArray(salt+hash)` form is WRONG +for qb5: login 401s on it; verify() base64-decodes the two halves separately.) -## Docker Compose +## Deployment (current) -```yaml -qbittorrent: - image: lscr.io/linuxserver/qbittorrent:latest - container_name: qbittorrent - restart: unless-stopped - environment: - - PUID=1000 - - PGID=1000 - - TZ=America/New_York - - UMASK_SET=022 - volumes: - - /opt/qbittorrent/config:/config - - /mnt/media/downloads:/downloads - - /mnt/media/downloads/incomplete:/downloads/incomplete - ports: - - "8080:8080" - networks: [appnet] +Quadlet unit `qbittorrent.container` from this repo +(`frankbook-pro/qbittorrent/quadlet/`), installed inside the podman machine at +`/home/core/.config/containers/systemd/qbittorrent.service` by the +frankbook-pro handler in `scripts/deploy-remote.sh`: + +```ini +[Container] +ContainerName=qbittorrent +Image=lscr.io/linuxserver/qbittorrent:4.6.7 +Network=gluetun.container +Environment=PUID=0 +Environment=PGID=0 +Environment=TZ=America/Los_Angeles +Environment=UMASK_SET=022 +Volume=/Volumes/COMPLETE/qbittorrent-data:/config +Volume=/Volumes/COMPLETE:/Volumes/COMPLETE +Volume=/Volumes/INCOMPLETE:/Volumes/INCOMPLETE + +[Service] +TimeoutStartSec=900 +Restart=always ``` ## Gotchas (verified live) @@ -81,9 +101,17 @@ qbittorrent: download queue" in the arr logs) after any restart. - API login from `curl` needs a `Referer: http://:/` header (CSRF protection) or POSTs get rejected even with a valid SID. +- Cookie-name quirk by version: qB 5.x names its WebUI session cookie + `QBT_SID_`; 4.6.7 uses plain `SID`. Any automation must parse the + cookie generically (e.g. `grep -oE '[A-Za-z_]*SID[A-Za-z0-9_]*=[^;[:space:]]*'`) + instead of hard-coding a port-suffixed name, or it fails with 403 cascades + that never reach qB as failed logins. +- Egress verification for this stack must run **inside the gluetun container** + (`podman exec gluetun wget -qO- https://ipinfo.io/json`); running the same + probe one ssh-context out returns the residential IP — a false leak alarm. - Ensure umask is set to `022` so downloaded files are readable by arr apps. -- Monitor bandwidth limits to avoid saturating the network. ## See Also - [[ARR-Stack]] — full *arr stack documentation +- [[Gluetun]] — the WireGuard tunnel this container shares diff --git a/serverAppConfigs-docs/Dankserver/radarr.md b/serverAppConfigs-docs/Dankserver/radarr.md index ed47065..1bbc296 100644 --- a/serverAppConfigs-docs/Dankserver/radarr.md +++ b/serverAppConfigs-docs/Dankserver/radarr.md @@ -1,52 +1,69 @@ +--- +type: reference +title: Radarr +description: Radarr movie manager in the *arr stack on FrankBook-Pro — live quadlet deployment, ports, volumes, and wiring facts. +tags: [radarr, arr-stack, frankbook-pro] +timestamp: 2026-09-03T00:00:00Z +--- + # Radarr -Radarr manages movies in the *arr stack on Dankserver. It automatically searches, downloads, and organizes movies from indexers into the Jellyfin media library. +Radarr manages movies in the *arr stack. The stack runs on **FrankBook-Pro** +(the Mac mini) as quadlet units inside its podman machine — not on Dankserver. +It searches, downloads, and organizes movies from indexers into the Jellyfin +movie library. -**Host:** Dankserver — **Hostname:** `radarr.dankserver.local` — **Docs:** https://wiki.servarr.com/radarr +**Host:** FrankBook-Pro (podman machine) — **Access:** direct port `7878` (no reverse-proxy vhost; the *arr stack is exempt by construction from the Anubis guard chain) — **Docs:** https://wiki.servarr.com/radarr ## Facts | Item | Value | |------|-------| -| Image | `lscr.io/linuxserver/radarr:latest` (v6 stable) | +| Image | `lscr.io/linuxserver/radarr:latest` (v6 line; v6.3.x verified live 2026-08-30) | | Port | 7878 (host) → 7878 (container) | +| Env | `PUID=0`, `PGID=0`, `TZ=America/Los_Angeles`, `UMASK_SET=022` | +| Config root | `/Volumes/COMPLETE/radarr-data:/config` | | Min RAM | 512 MB | | Metadata | TMDB / TheMovieDB API | -## Docker Compose +## Deployment (current) -```yaml -radarr: - image: lscr.io/linuxserver/radarr:latest - container_name: radarr - restart: unless-stopped - environment: - - PUID=1000 - - PGID=1000 - - TZ=America/New_York - - UMASK_SET=022 - volumes: - - /opt/radarr/config:/config - - /mnt/media/movies:/movies - - /mnt/media/downloads:/downloads - ports: - - "7878:7878" - networks: [appnet] +Quadlet unit `radarr.container` from this repo (`frankbook-pro/radarr/quadlet/`) +is installed inside the podman machine at +`/home/core/.config/containers/systemd/radarr.service` by the frankbook-pro +handler in `scripts/deploy-remote.sh`. Unit shape: + +```ini +[Container] +ContainerName=radarr +Image=lscr.io/linuxserver/radarr:latest +Environment=PUID=0 +Environment=PGID=0 +Environment=TZ=America/Los_Angeles +Environment=UMASK_SET=022 +Volume=/Volumes/COMPLETE/radarr-data:/config +PublishPort=7878:7878 + +[Service] +TimeoutStartSec=900 +Restart=always ``` ## Configuration -1. Add Prowlarr as the indexer source. -2. Add qBittorrent as the download client with the `movies` category. +1. Add Prowlarr as the indexer source (the YTS indexer row feeds Radarr — see [[Prowlarr]]). +2. Add qBittorrent as the download client with the `movies` category ([[qBittorrent]]). 3. Set quality profile and cutoff quality. -4. Set root folder to `/movies`. +4. Set the root folder to the movies root under the COMPLETE volume (Radarr + imports from where [[qBittorrent]] drops completed downloads; first verified + grab+import was a 2160p Dark Knight test on 2026-08-30). 5. Add movies and verify downloads. ## Gotchas - Radarr v6 is the current stable (v6.3.x as of 2026-08). `:latest` points to the current release. - Movie renaming produces `Title (Year)` format. Jellyfin scanner handles this. -- File permissions: qBittorrent downloads as PUID; arr apps must read/move files. +- File permissions: qBittorrent downloads as PUID=0; arr apps must read/move files. ## See Also diff --git a/serverAppConfigs-docs/Dankserver/readarr.md b/serverAppConfigs-docs/Dankserver/readarr.md index 8f78b9e..56f5693 100644 --- a/serverAppConfigs-docs/Dankserver/readarr.md +++ b/serverAppConfigs-docs/Dankserver/readarr.md @@ -1,55 +1,81 @@ +--- +type: reference +title: Readarr +description: Readarr ebook/audiobook manager in the *arr stack on FrankBook-Pro — retired upstream, pinned image, parked qB download client. +tags: [readarr, arr-stack, frankbook-pro] +timestamp: 2026-09-03T00:00:00Z +--- + # Readarr -> **RETIRED (May 2026).** The Servarr Team retired Readarr: its metadata became unusable and the community migration to Open Library stalled. There is no upstream development. Alternatives: the Bookshelf community fork, or the Calibre content server. See [Readarr (Retired)](https://wiki.servarr.com/readarr). +> **RETIRED UPSTREAM (May 2026).** The Servarr Team retired Readarr: its +> metadata became unusable and the community migration to Open Library stalled. +> There is no upstream development. Alternatives: the Bookshelf community fork, +> or the Calibre content server. This instance still runs on a pinned image +> tag; see below. -Readarr manages ebooks and audiobooks in the *arr stack on Dankserver. It automatically searches, downloads, and organizes books into the Calibre library. +Readarr manages ebooks and audiobooks in the *arr stack. The stack runs on +**FrankBook-Pro** (the Mac mini) as quadlet units inside its podman machine — +not on Dankserver. It organizes books into the Calibre library that +[[Calibre-Web]] serves. -**Host:** Dankserver — **Hostname:** `readarr.dankserver.local` — **Docs:** https://wiki.servarr.com/readarr +**Host:** FrankBook-Pro (podman machine) — **Access:** direct port `8787` (no reverse-proxy vhost; the *arr stack is exempt by construction from the Anubis guard chain) — **Docs:** https://wiki.servarr.com/readarr ## Facts | Item | Value | |------|-------| -| Image | `lscr.io/linuxserver/readarr:latest` (v0.2.x development) | +| Image | `lscr.io/linuxserver/readarr:amd64-1.0.980` — **pinned tag** (LSIO ships no untagged `latest` for readarr; the tag was pinned after a manifest probe) | | Port | 8787 (host) → 8787 (container) | +| Env | `PUID=0`, `PGID=0`, `TZ=America/Los_Angeles`, `UMASK_SET=022` | +| Config root | `/Volumes/COMPLETE/readarr-data:/config` | | Min RAM | 256 MB | -| Metadata | Goodreads / StoryGraph | +| Metadata | Goodreads / StoryGraph (provider status at retirement) | -## Docker Compose +## Deployment (current) -```yaml -readarr: - image: lscr.io/linuxserver/readarr:latest - container_name: readarr - restart: unless-stopped - environment: - - PUID=1000 - - PGID=1000 - - TZ=America/New_York - - UMASK_SET=022 - volumes: - - /opt/readarr/config:/config - - /mnt/media/books:/books - - /mnt/media/downloads:/downloads - ports: - - "8787:8787" - networks: [appnet] +Quadlet unit `readarr.container` from this repo (`frankbook-pro/readarr/quadlet/`) +is installed inside the podman machine at +`/home/core/.config/containers/systemd/readarr.service` by the frankbook-pro +handler in `scripts/deploy-remote.sh`. Unit shape: + +```ini +[Container] +ContainerName=readarr +Image=lscr.io/linuxserver/readarr:amd64-1.0.980 +Environment=PUID=0 +Environment=PGID=0 +Environment=TZ=America/Los_Angeles +Environment=UMASK_SET=022 +Volume=/Volumes/COMPLETE/readarr-data:/config +PublishPort=8787:8787 + +[Service] +TimeoutStartSec=900 +Restart=always ``` ## Configuration -1. Add Prowlarr as the indexer source (torrent indexers with book content). -2. Add qBittorrent as the download client with the `books` category. +1. Add Prowlarr as the indexer source (torrent indexers with book content; + the Byrutor row feeds Readarr — see [[Prowlarr]]). +2. The qBittorrent download client is **parked**: Readarr's abandoned client + fails auth against newer qB Web-API versions (see [[qBittorrent]] for the + 4.6.7 pin rationale); re-enable only after the image changes. Until then, + books are imported manually or via Calibre tooling. 3. Set author profile (format preference: epub, mobi, etc.). 4. Set quality profile for audiobooks (320 kbps MP3, 128 kbps, lossless). -5. Set root folder to `/books`. -6. Add authors and verify downloads. +5. Set the root folder to the books root under the COMPLETE volume. ## Gotchas -- Readarr is in development (~v0.2.x). Some features may be incomplete. -- Calibre integration is folder-based, not API-based. Readarr drops files into `/books` which Calibre-Web serves. -- Not all indexers have all formats (epub, mobi, pdf). Goodreads/StoryGraph metadata helps match editions. +- Readarr is abandoned upstream (retired May 2026; last line was 0.4.x before + the final tags). The pinned `amd64-1.0.980` tag exists precisely because + `:latest` does not exist for this image on LSIO. +- Calibre integration is folder-based, not API-based. Readarr drops files into + the books root which [[Calibre-Web]] serves. +- Not all indexers carry all formats (epub, mobi, pdf). Goodreads/StoryGraph + metadata helps match editions while those providers still respond. ## See Also diff --git a/serverAppConfigs-docs/Dankserver/redis.md b/serverAppConfigs-docs/Dankserver/redis.md index 21b9cca..fcdc1ea 100644 --- a/serverAppConfigs-docs/Dankserver/redis.md +++ b/serverAppConfigs-docs/Dankserver/redis.md @@ -1,40 +1,67 @@ +--- +type: reference +title: Redis (RomM Cache / Queue) +description: Redis 7-alpine cache and task-queue backend for RomM on Dankserver — quadlet unit, network alias topology, and backup path. +tags: [redis, romm, dankserver] +timestamp: 2026-09-03T00:00:00Z +--- + # Redis (RomM Cache / Queue) -Redis 7 provides the caching and task queue backend for RomM on Dankserver. RomM 5.2.0 requires Redis (or Valkey) for its task queue. +Redis 7 provides the caching and task-queue backend for [[RomM]] on Dankserver. +RomM requires Redis (or Valkey) for its task queue; this deployment runs +stock `redis:7-alpine` — no Valkey here, unlike the SearXNG cache on +Dankclaw ([[Valkey]]). -**Host:** Dankserver — **Docs:** https://redis.io/docs/ +**Host:** Dankserver — container name `romm-redis`, unit `romm-redis.service` +(user-manager quadlet from `dankserver/romm/quadlet/romm-redis.container`). -## Facts +## Facts (verified from the live unit) | Item | Value | |------|-------| -| Image | `docker.io/redis:7-alpine` | -| Port | 6379 (internal, within `appnet`) | -| Data volume | `/opt/romm/redis` | -| Auth | None (local-only, no password needed) | +| Image | `docker.io/library/redis:7-alpine` | +| Port | 6379 — internal only; no `PublishPort`, so it is unreachable from the host network by construction | +| Network | `dankserver_appnet` with `alias=redis` — that alias is what makes `REDIS_HOST=redis` in the RomM unit resolve | +| Data volume | `/home/dank/Containers/romm/redis:/data` | +| Auth | None — safe precisely because the container is not published anywhere; only appnet members can reach it | -## Docker Compose +## Unit shape (as deployed) -```yaml -redis: - image: docker.io/redis:7-alpine - container_name: romm-redis - restart: unless-stopped - volumes: - - /opt/romm/redis:/data - healthcheck: - test: ["CMD", "redis-cli", "ping"] - interval: 10s - timeout: 5s - retries: 3 +```ini +[Container] +ContainerName=romm-redis +Image=docker.io/library/redis:7-alpine +Network=dankserver_appnet:alias=redis +Volume=/home/dank/Containers/romm/redis:/data +HealthCmd=redis-cli ping +HealthInterval=10s +HealthTimeout=5s +HealthRetries=3 + +[Service] +Restart=always +RestartSec=5 + +[Install] +WantedBy=default.target ``` +No `EnvironmentFile` — there is nothing secret in this unit; the auth-less +posture is enforced by network topology (alias-only reachability), not by a +password. If a future client ever needs Redis from outside the appnet, add +`PublishPort` **and** a `requirepass` in the same change — never just the port. + ## Backup ```bash -sudo rsync -a /opt/romm/redis /mnt/backup/romm-redis/ +sudo rsync -a /home/dank/Containers/romm/redis /mnt/backup/romm-redis/ ``` +Redis here is cache + queue state; losing it costs queued jobs and cache warm, +not the library (the database lives in [[MariaDB]]). + ## See Also - [[RomM]] — service that uses this cache +- [[Valkey]] — the SearXNG-side equivalent on Dankclaw diff --git a/serverAppConfigs-docs/Dankserver/sonarr.md b/serverAppConfigs-docs/Dankserver/sonarr.md index a71d98e..5bdf482 100644 --- a/serverAppConfigs-docs/Dankserver/sonarr.md +++ b/serverAppConfigs-docs/Dankserver/sonarr.md @@ -1,53 +1,70 @@ +--- +type: reference +title: Sonarr +description: Sonarr TV manager in the *arr stack on FrankBook-Pro — live quadlet deployment, ports, volumes, and wiring facts. +tags: [sonarr, arr-stack, frankbook-pro] +timestamp: 2026-09-03T00:00:00Z +--- + # Sonarr -Sonarr manages TV shows in the *arr stack on Dankserver. It automatically searches, downloads, and organizes episodes from indexers into the Jellyfin media library. +Sonarr manages TV shows in the *arr stack. The stack runs on **FrankBook-Pro** +(the Mac mini) as quadlet units inside its podman machine — not on Dankserver. +It searches, downloads, and organizes episodes from indexers into the Jellyfin +TV library. -**Host:** Dankserver — **Hostname:** `sonarr.dankserver.local` — **Docs:** https://wiki.servarr.com/sonarr +**Host:** FrankBook-Pro (podman machine) — **Access:** direct port `8989` (no reverse-proxy vhost; the *arr stack is exempt by construction from the Anubis guard chain) — **Docs:** https://wiki.servarr.com/sonarr ## Facts | Item | Value | |------|-------| -| Image | `lscr.io/linuxserver/sonarr:latest` (v4 stable) | +| Image | `lscr.io/linuxserver/sonarr:latest` (v4 line) | | Port | 8989 (host) → 8989 (container) | +| Env | `PUID=0`, `PGID=0`, `TZ=America/Los_Angeles`, `UMASK_SET=022` | +| Config root | `/Volumes/COMPLETE/sonarr-data:/config` | | Min RAM | 512 MB | | Metadata | TMDB / TVDB | -## Docker Compose +## Deployment (current) -```yaml -sonarr: - image: lscr.io/linuxserver/sonarr:latest - container_name: sonarr - restart: unless-stopped - environment: - - PUID=1000 - - PGID=1000 - - TZ=America/New_York - - UMASK_SET=022 - volumes: - - /opt/sonarr/config:/config - - /mnt/media/tv:/tv - - /mnt/media/downloads:/downloads - ports: - - "8989:8989" - networks: [appnet] +Quadlet unit `sonarr.container` from this repo (`frankbook-pro/sonarr/quadlet/`) +is installed inside the podman machine at +`/home/core/.config/containers/systemd/sonarr.service` by the frankbook-pro +handler in `scripts/deploy-remote.sh`. Unit shape: + +```ini +[Container] +ContainerName=sonarr +Image=lscr.io/linuxserver/sonarr:latest +Environment=PUID=0 +Environment=PGID=0 +Environment=TZ=America/Los_Angeles +Environment=UMASK_SET=022 +Volume=/Volumes/COMPLETE/sonarr-data:/config +PublishPort=8989:8989 + +[Service] +TimeoutStartSec=900 +Restart=always ``` ## Configuration -1. Add Prowlarr as the indexer source. -2. Add qBittorrent as the download client with the `tv` category. +1. Add Prowlarr as the indexer source (see [[Prowlarr]] — the feed route is `/{indexerId}/api`). +2. Add qBittorrent as the download client with the `tv` category ([[qBittorrent]]). 3. Set quality profile, cutoff, and minimum/maximum episode sizes. -4. Set root folder to `/tv`. -5. Add series and verify downloads. +4. Set the root folder to the TV root under the COMPLETE volume (Sonarr imports + from where [[qBittorrent]] drops completed downloads). +5. Add a test series and verify the grab → download → import chain end-to-end. ## Gotchas - Sonarr v4 is the current stable. The v3 branch uses the `:v3` tag. - Anime has different quality profiles and naming conventions than Standard series. - Missing episodes: set "Unmonitor Missing Episodes" to auto-unmonitor old episodes. -- Timezone-sensitive scheduler: ensure all containers use the same TZ. +- Timezone-sensitive scheduler: every unit in the stack runs + `TZ=America/Los_Angeles`; keep them uniform. ## See Also diff --git a/serverAppConfigs-docs/Infrastructure/Homepage.md b/serverAppConfigs-docs/Infrastructure/Homepage.md index 30a411e..fd21d17 100644 --- a/serverAppConfigs-docs/Infrastructure/Homepage.md +++ b/serverAppConfigs-docs/Infrastructure/Homepage.md @@ -4,9 +4,9 @@ A password-protected web site on Dankclaw lists the services that are up, with a **Served by:** Caddy, `file_server` + `forward_auth` (Authentik SSO) — **Docs:** this page -## Status — 2026-08-23: deployed to production +## Status — deployed to production (2026-08-23), on the naked domain since 2026-08-24 -The homepage is live on Dankclaw. `./scripts/deploy.sh dankclaw` copies the static assets to `/srv/homepage/`, installs the status checker (systemd timer, every 3 min, writes `status.json`), writes `deployed.js` (the last master deployment datetime), renders the Caddyfile (the shared basicauth hash from the host `.env`), reloads Caddy, and checks health. 146 tests pass. The Caddyfile auth uses a `route` block with `forward_auth` (see [Auth](#auth)); the caddy container mounts the host's `/srv/homepage` (not the repo source) so the generated files serve. +The homepage is live on Dankclaw. `./scripts/deploy.sh dankclaw` copies the static assets to `/srv/homepage/`, installs the status checker (systemd timer, every 3 min, writes `status.json`), writes `deployed.js` (the last master deployment datetime), renders the Caddyfile (the shared basicauth hash from the host `.env`), reloads Caddy, and checks health. The Caddyfile auth uses a `route` block with `forward_auth` (see [Auth](#auth)); the caddy container mounts the host's `/srv/homepage` (not the repo source) so the generated files serve. **Moved to the naked domain (2026-08-24):** the homepage now serves `franksdank.cloud` and `www.franksdank.cloud`. The old names `dankclaw.franksdank.cloud` and `dankserver.franksdank.cloud` redirect to it. Authentication moved from per-page basicauth to Authentik `forward_auth` (see [Authentik](Authentik.md)). @@ -28,7 +28,7 @@ The site has two pages. The root page lists the user services. The `/admin/` pag ```mermaid graph TD - subgraph site["dankclaw.franksdank.cloud (Caddy)"] + subgraph site["franksdank.cloud + www (Caddy)"] ROOT["/ user services
(shared password)"] ADMIN["/admin/ admin services
(operator password)"] HOW["/how/ how it is built
(deferred)"] @@ -85,7 +85,9 @@ flowchart TD **Admin services** (`/admin/`): Hermes, Grafana, Prometheus, Loki, Caddy, Pi-hole, Gluetun, the LLM fleet, and the low-level backends (mariadb, redis, Postgres, node-exporter, alloy). The backends show status only. They get a link only where a UI is meaningful. -**Excluded for now:** the *arr stack (Radarr, Sonarr, Lidarr, Readarr, Prowlarr, qBittorrent). It is not started. It is a separate effort, possibly on a different host. +**Excluded from the listing:** the *arr stack + qBittorrent (Prowlarr, Sonarr, +Radarr, Lidarr, Readarr, qB) — live on FrankBook-Pro but operator-only: no +vhosts, direct IP:port access only. See [[FrankBook-Pro]]. ## Layout diff --git a/serverAppConfigs-docs/Infrastructure/Prometheus.md b/serverAppConfigs-docs/Infrastructure/Prometheus.md index 4eda4c8..69808a7 100644 --- a/serverAppConfigs-docs/Infrastructure/Prometheus.md +++ b/serverAppConfigs-docs/Infrastructure/Prometheus.md @@ -2,7 +2,9 @@ Prometheus collects metrics from every service on Dankclaw by scraping their `/metrics` endpoints. It feeds the Grafana dashboards. The `node-exporter` containers may add podman/cgroup metrics for full host visibility. -**Host:** Dankclaw — **Hostname:** `prometheus.dankclaw.local` — **Port:** 9090 — **Docs:** https://prometheus.io/docs +**Host:** Dankclaw — **Vhost:** `prometheus.franksdank.cloud` (guarded: Anubis → +Authentik; post-auth the Caddy vhost routes straight to `prometheus:9090`) — +**Port:** 9090 — **Docs:** https://prometheus.io/docs ## Facts diff --git a/serverAppConfigs-docs/LLM/DFlash DSpark Speculative Decoding.md b/serverAppConfigs-docs/LLM/DFlash DSpark Speculative Decoding.md index 1952d3f..3912f93 100644 --- a/serverAppConfigs-docs/LLM/DFlash DSpark Speculative Decoding.md +++ b/serverAppConfigs-docs/LLM/DFlash DSpark Speculative Decoding.md @@ -160,9 +160,9 @@ The DFlash draft is not a standalone model. It must pair with its target model. ## Deployment on Dankserver (NVIDIA RTX 3090) -The Dankserver llama.cpp deployment (`frank-default-small`, Qwen3.6-35B-A3B) is **active** on Dankserver (port 7770) as of the 2026-08-17 redo (the earlier 2026-08-16/17 retirement of this service was reversed when the PP split was retired). The vLLM material below documents the archived AWQ/DFlash path on the same hardware. +The Dankserver llama.cpp deployment (`frank-small`, Qwen3.6-35B-A3B) is **active** on Dankserver (port 7770) as of the 2026-08-17 redo (the earlier 2026-08-16/17 retirement of this service was reversed when the PP split was retired). The vLLM material below documents the archived AWQ/DFlash path on the same hardware. -> **DFlash retired from active service.** `DFlash` (draft-dflash) was tested initially but did not deliver the desired speed gains under the `frank-default-small` workload (see ngram-mod benchmarks below). The `Alittlehammmer/Qwen3.6-35B-A3B-DFlash` draft GGUF remains in `/home/dank/models/` as reference material only. +> **DFlash retired from active service.** `DFlash` (draft-dflash) was tested initially but did not deliver the desired speed gains under the `frank-small` workload (see ngram-mod benchmarks below). The `Alittlehammmer/Qwen3.6-35B-A3B-DFlash` draft GGUF remains in `/home/dank/models/` as reference material only. The vLLM material below documents the archived AWQ/DFlash path on the same hardware. The RTX 3090 is Ampere (compute capability 8.6). Use these conditions: @@ -195,7 +195,7 @@ docker run --rm --name vllm-qwen36-dflash \ ## Deployment on Dankclaw (AMD Strix Halo gfx1151) -`frank-default-large` on Dankclaw runs the llama.cpp pipeline-parallel head (Qwen3.8-27B-Uncensored Q6_K) on port 7770, RPC-split with the Dankserver worker. Spec is the standalone MTP draft over the ngram-mod fallback, 1 slot at 262144 ctx, q8_0/f16 KV, head GPU side ROCm0. See [[qwen3.8-spec-matrix]] and [[Qwen3.8 PP Deployment]] for the current state and the 2026-08-15 Vulkan0/ROCm0 high-context bench. +`frank-large` on Dankclaw ran the llama.cpp pipeline-parallel head (Qwen3.8-27B-Uncensored Q6_K) on port 7770, RPC-split with the Dankserver worker. Spec was the standalone MTP draft over the ngram-mod fallback, 1 slot at 262144 ctx, q8_0/f16 KV, head GPU side ROCm0. This page is a historical record of that era (mid-August 2026); for the current deployment see [[kingjones-strix-rocmfp4]]. History: before `--spec-default`, the box ran DSpark (`draft-dspark`, retired 2026-08-15 after a ROCm illegal-memory-access crash under two concurrent 16k prompts) and before that bundled MTP (`draft-mtp`, retired same day). DFlash was retired on 2026-08-14 (premature-EOS under parallel load). The old DFlash draft GGUF (`Qwen3.6-27B-DFlash-Q8_0.gguf`), the MTP-only drafter (`Qwen3.6-27B-MTP-ONLY-Q8_0.gguf`), and the DSpark draft (`Qwen3.8-27B-DSpark-Q8_0.gguf`) remain in `/home/dank/models/` as reference only. diff --git a/serverAppConfigs-docs/LLM/Dankclaw Improvements.md b/serverAppConfigs-docs/LLM/Dankclaw Improvements.md index 95521c9..bce06a5 100644 --- a/serverAppConfigs-docs/LLM/Dankclaw Improvements.md +++ b/serverAppConfigs-docs/LLM/Dankclaw Improvements.md @@ -14,7 +14,7 @@ marked "verify first". Re-verified 2026-08-15/16; corrections marked below. (b10433): Vulkan 25.13 t/s vs ROCm 24.33 t/s decode at 16k; at 262k ctx Vulkan decodes 48% faster (5.68 vs 3.83 t/s). ROCm wins prefill (410 vs 302 t/s @64k). The "HIP out-performs Vulkan for decode" claim did not - hold on the 8060S. See [[frank-default-large-benchmark]]. + hold on the 8060S. See [[frank-large-benchmark]]. - **Power profile**: the `/sys/class/drm/card0/device/power_profile` file does not exist on this machine (checked 2026-08-15). GPU DPM is already `performance`, forced level `auto`. This item is N/A. @@ -40,7 +40,7 @@ lifted to 114 GiB. ROCm/SMI still reports a 96 GiB VRAM carve-out (VGM) — a different, driver-reported figure that has always been larger than the kernel cap. This split is the Strix Halo GTT/VGM design. It drives the batch/ubatch memory -limits documented in [[frank-default-large-benchmark]]. +limits documented in [[frank-large-benchmark]]. ## 1. Self-Hosted Agentic Tools @@ -98,7 +98,7 @@ All require root and a reboot for the modprobe change. ## Sources -- [[frank-default-large-benchmark]] — measured backend/spec numbers +- [[frank-large-benchmark]] — measured backend/spec numbers - [[deployment]] — deploy and update process - AMD ROCm RDNA3.5 system optimization guide (gfx1151 memory/BIOS) - llama.cpp source: `ggml/CMakeLists.txt`, `ggml/src/ggml-hip/CMakeLists.txt`, @@ -107,7 +107,7 @@ All require root and a reboot for the modprobe change. ## See Also -- [[frank-default-large-benchmark]] +- [[frank-large-benchmark]] - [[DFlash DSpark Speculative Decoding]] - [[deployment]] - [[index]] diff --git a/serverAppConfigs-docs/LLM/Dankclaw System Specs.md b/serverAppConfigs-docs/LLM/Dankclaw System Specs.md index 918fd9d..33a447d 100644 --- a/serverAppConfigs-docs/LLM/Dankclaw System Specs.md +++ b/serverAppConfigs-docs/LLM/Dankclaw System Specs.md @@ -38,7 +38,7 @@ Dankclaw is an AMD APU server for CIRU ROCmFPX llama.cpp inference. The host run | Runtime | FastFlowLM 0.9.45 + XRT (installed 2026-08-16; **retired 2026-08-17**) | | Status | Not in service. Research only. See [[FastFlowLM NPU Inference]] | -The NPU is retired; the 52625 port and the `frank-default-small` name now serve the CIRU ROCmFPX llama.cpp runtime (see [[ciru-activefpx-promptforge]]). +The NPU is retired; the 52625 port and the `frank-small` name now serve the CIRU ROCmFPX llama.cpp runtime (see [[ciru-activefpx-promptforge]]). ### ROCm @@ -93,7 +93,7 @@ cable between claw and server is required for 10G. - Unified memory eliminates separate VRAM limits. The GPU uses system RAM. - The GPU budget is the rocm-smi figure: 64 GiB VRAM reported by rocm-smi (SVM-backed). The older 96 GiB figure was the addressable SVM pool, not the budget. Trust rocm-smi and the runtime; do not use `free` or `dmidecode` for the GPU budget. -- The active service is `frank-default-large` on port 7770 (moved from 52625 on 2026-08-22): CIRU ROCmFPX llama.cpp serving kingjones/Qwen3.8-27B-Uncensored-ROCmFP4-STRIX-MTP (Q6 AGENT dense, 262144 ctx, standalone MTP Q4_0 head). See [[kingjones-strix-mtp]]. +- The active service is `frank-large` on port 7770 (moved from 52625 on 2026-08-22): CIRU ROCmFPX llama.cpp serving kingjones/Qwen3.8-27B-Uncensored-ROCmFP4-STRIX-MTP (Q6 AGENT dense, 262144 ctx, standalone MTP Q4_0 head). See [[kingjones-strix-mtp]]. - The runtime requires ROCm 7.15 (model card requirement). The system ROCm is 7.2.4; the retired ling3-ciru venv bundles a self-contained TheRock ROCm 7.15 SDK that the serve script puts first in `LD_LIBRARY_PATH`. - The retired vLLM venvs (`/home/dank/vllm-venv`, `/home/dank/vllm-vk-venv`) were moved to `/home/dank/.AGENTTRASH/` on 2026-08-18. - 1.1 TB free disk space is ample for model storage. diff --git a/serverAppConfigs-docs/LLM/Dankserver System Specs.md b/serverAppConfigs-docs/LLM/Dankserver System Specs.md index 3816032..4aa0022 100644 --- a/serverAppConfigs-docs/LLM/Dankserver System Specs.md +++ b/serverAppConfigs-docs/LLM/Dankserver System Specs.md @@ -60,7 +60,7 @@ Dankserver is an NVIDIA GPU server for vLLM inference. The host runs Ubuntu 26.0 ### Active Services -The active service on Dankserver is `frank-default-small.service`: the llama.cpp Ornith-1.5-35B-A3B CRACK (Q6_K) on port 7770, with expert tensors selected by `--override-tensor`; every full-attention block plus blocks 35–40 remain on CUDA. The earlier PP worker (`frank-pp-worker.service`) was retired with the 2026-08-17 redo. See [[deployment]]. +The active service on Dankserver is `frank-small.service`: the llama.cpp Ornith-1.5-35B-A3B CRACK (Q6_K) on port 7770, with expert tensors selected by `--override-tensor`; every full-attention block plus blocks 35–40 remain on CUDA. The earlier PP worker (`frank-pp-worker.service`) was retired with the 2026-08-17 redo. See [[deployment]]. ## Hardware Relevance diff --git a/serverAppConfigs-docs/LLM/FastFlowLM NPU Inference.md b/serverAppConfigs-docs/LLM/FastFlowLM NPU Inference.md index 21fe384..32d94c6 100644 --- a/serverAppConfigs-docs/LLM/FastFlowLM NPU Inference.md +++ b/serverAppConfigs-docs/LLM/FastFlowLM NPU Inference.md @@ -1,7 +1,7 @@ > **SUPERSEDED 2026-08-17.** The Frank redo retired this topology. > See [frank-redo-2026-08-17.md](frank-redo-2026-08-17.md) and > [deployment.md](deployment.md) for the active configuration. -> The `frank-default-small` name and port 52625 now belong to the vLLM +> The `frank-small` name and port 52625 now belong to the vLLM > service on Dankclaw (nameistoken Quark W8A8); this page is archive. --- @@ -19,7 +19,7 @@ timestamp: 2026-08-16 # FastFlowLM NPU Inference -FastFlowLM (FLM) runs LLMs entirely on the AMD Ryzen AI NPU. It targets XDNA2 chips: Strix, Strix Halo, Kraken, and Gorgon Point. The project describes itself as "Ollama, but deeply optimized for NPUs." As of 2026-08-16, FLM is installed on Dankclaw, the NPU validates, and `frank-default-small` (port 52625) serves in production. See Promotion. +FastFlowLM (FLM) runs LLMs entirely on the AMD Ryzen AI NPU. It targets XDNA2 chips: Strix, Strix Halo, Kraken, and Gorgon Point. The project describes itself as "Ollama, but deeply optimized for NPUs." As of 2026-08-16, FLM is installed on Dankclaw, the NPU validates, and `frank-small` (port 52625) serves in production. See Promotion. ## Verdict (2026-08-16) @@ -168,7 +168,7 @@ Proposed role: a small, always-on, low-power endpoint for triage, summarization, - `gpt-oss:20b` pulled (4/4 files verified, 13.8 GB `model.q4nx` + tokenizer) into `~/.config/flm/models/GPT-OSS-20B-NPU2/`. - `qwythos:9b` (Huihui-Qwythos-9B-Claude-Mythos-5-1M-abliterated-NPU2) installed 2026-08-17 via `flm-add.py` (downloaded from the HF repo; stdlib-only, no pip needed). Tag registered in the user registry `~/.config/flm/model_list.json` (a copy of the v1.0.1 system registry + the custom entry); kernels symlinked `~/.config/flm/xclbins/Huihui-...-NPU2 -> /opt/fastflowlm/share/flm/xclbins/Qwen3.5-9B-NPU2`. The service env exports `FLM_CONFIG_PATH` and `FLM_XCLBIN_PATH` so the tag resolves (without them flm hits the unknown-tag fallback, see the incident below). - `flm serve gpt-oss:20b --host 0.0.0.0 -p 52625 --pmode performance` runs as a nohup process. It is not a systemd unit. It does not survive a reboot. -- The `llama-server` (frank-default-large, the PP head) holds an fd on `/dev/accel/accel0` from its own startup (device enumeration, not compute). FLM opened the same device concurrently without conflict. Verified live 2026-08-16. +- The `llama-server` (frank-large, the PP head) holds an fd on `/dev/accel/accel0` from its own startup (device enumeration, not compute). FLM opened the same device concurrently without conflict. Verified live 2026-08-16. ## Measured Results (2026-08-16, gpt-oss-20b on the Dankclaw NPU) @@ -186,7 +186,7 @@ Long-context prefill is not yet measured (runs 1-3 used under 200 prompt tokens) ## Model Bakeoff (measured 2026-08-16, 4 models) -All runs on the Dankclaw NPU (50 TOPS Strix Halo), single stream, `--pmode performance`, PP head (frank-default-large) serving concurrently on 7770. Decode t/s is the FLM-reported rate. Vision accuracy = ground-truth elements out of 4 (text SPECTRUM, red circle left, blue square right, three green triangles bottom). +All runs on the Dankclaw NPU (50 TOPS Strix Halo), single stream, `--pmode performance`, PP head (frank-large) serving concurrently on 7770. Decode t/s is the FLM-reported rate. Vision accuracy = ground-truth elements out of 4 (text SPECTRUM, red circle left, blue square right, three green triangles bottom). | Model | Tag | Weights | Decode t/s (short) | 8k prefill t/s | 8k decode t/s | Vision decode t/s | Vision accuracy | Max ctx (registry) | |-------|-----|---------|-------------------:|---------------:|--------------:|------------------:|----------------|--------------------| @@ -204,21 +204,21 @@ Notes: ## Promotion (2026-08-16) -`frank-default-small` now runs the NPU endpoint on Dankclaw (was the Dankserver llama.cpp service). Unit: `scripts/frank-default-small.service` (symlinked into `/etc/systemd/system`), wrapper `scripts/serve-flm-small.sh`, tunables `scripts/frank-default-small.env`. `LimitMEMLOCK=infinity` is set in the unit. Default model: `gemma4-it:e4b`. Swap `FLM_MODEL` in the env to switch. +`frank-small` now runs the NPU endpoint on Dankclaw (was the Dankserver llama.cpp service). Unit: `scripts/frank-small.service` (symlinked into `/etc/systemd/system`), wrapper `scripts/serve-flm-small.sh`, tunables `scripts/frank-small.env`. `LimitMEMLOCK=infinity` is set in the unit. Default model: `gemma4-it:e4b`. Swap `FLM_MODEL` in the env to switch. ### Boot policy (2026-08-17) -The `frank-default-small` unit is disabled for boot. Only the PP pair (`frank-default-large` + `frank-pp-worker`) starts at boot. The unit file was removed from `/etc/systemd/system`; the running FLM service keeps serving until stopped or rebooted. To restore the endpoint, run these commands on Dankclaw: +The `frank-small` unit is disabled for boot. Only the PP pair (`frank-large` + `frank-pp-worker`) starts at boot. The unit file was removed from `/etc/systemd/system`; the running FLM service keeps serving until stopped or rebooted. To restore the endpoint, run these commands on Dankclaw: ``` -sudo ln -sf /home/dank/vllmScripts/scripts/frank-default-small.service /etc/systemd/system/frank-default-small.service +sudo ln -sf /home/dank/vllmScripts/scripts/frank-small.service /etc/systemd/system/frank-small.service sudo systemctl daemon-reload -sudo systemctl enable frank-default-small +sudo systemctl enable frank-small ``` Live config (2026-08-16): `FLM_PMODE=turbo`, `FLM_ASR=1` (loads Whisper-V3-Turbo-NPU2; exposes `/v1/audio/transcriptions`), `FLM_CTX_LEN=131072` (verified max — Gemma4 natively supports 128K and the NPU budget fits it; KV occupancy measured at 0.11% for a 123-token exchange, decode 12.0 t/s, 13 GiB headroom). -The PP split was renamed `frank-pp-head` → `frank-default-large` (2026-08-16, commit `48142f5`). +The PP split was renamed `frank-pp-head` → `frank-large` (2026-08-16, commit `48142f5`). Model swap (2026-08-16, commit `50c55ee`): `FLM_MODEL=qwen3.6-moe:35b-a3b`, `FLM_CTX_LEN=262144` (native max), `FLM_PMODE=turbo`, `FLM_ASR=1` kept. Decode measured 12.5-13.1 t/s. The Gemma4 live config above (131072 ctx) applied to `gemma4-it:e4b`. Swap `FLM_MODEL` and `FLM_CTX_LEN` back to restore it. @@ -277,7 +277,7 @@ graph TD Symptom: a client on dankware could not reach `qwen3.6-moe:35b-a3b` on port 52625. The journal shows three separate causes in the 14:19-15:03 window. 1. **EXEC 203 crash loop (14:19-14:20).** The exec bit was lost on `serve-flm-small.sh` on the target. The unit failed `status=203/EXEC: Permission denied` four times, then started after the bit was restored. The git mode is `100755` (commit `3f42210`), and a `git pull` restores the bit. Verify with `git ls-files -s scripts/serve-flm-small.sh`. -2. **Wrong model ID (14:29-14:52).** The client config still used the model ID `frank-default-small` (a service alias). FLM rejects that tag with `[ERROR] Model tag 'frank-default-small' is not supported.` Each such request also triggered the unknown-tag fallback below. +2. **Wrong model ID (14:29-14:52).** The client config still used the model ID `frank-small` (a service alias). FLM rejects that tag with `[ERROR] Model tag 'frank-small' is not supported.` Each such request also triggered the unknown-tag fallback below. 3. **Swap churn (14:48-15:03).** The swap `gemma4-it:e4b` → `qwen3.6-moe:35b-a3b` restarted the service several times. Each load of the 23 GB model takes about 1.5-2.5 minutes at 262144 ctx. The endpoint does not serve during a load. Fix: the client model ID must be the FLM registry tag `qwen3.6-moe:35b-a3b`. The working pi agent entry in `~/.pi/agent/models.json` is `baseUrl http://192.168.0.143:52625/v1`, `id qwen3.6-moe:35b-a3b`, `contextWindow 262144`, `reasoning true`, `input [text, image]`. Verified end-to-end from dankware (192.168.0.226) at 15:32 on 2026-08-16. @@ -314,7 +314,7 @@ pi sessions failed against this endpoint with `Stream ended without finish_reaso - **The FLM serve process is not under systemd.** A reboot of Dankclaw kills it. The PP head service is enabled and returns. The FLM process must be restarted by hand. A unit file is a natural next step. - **gpt-oss reasoning budget.** The model can spend its full token budget on `reasoning_content` and return empty content. Clients must handle or cap this. - **No llama.cpp GGUF path.** FLM uses its own pre-compiled kernels. Our UD-Q8_K_XL and HauhauCS builds are not importable. NPU work means FLM-specific model tags. -- **NPU production role (2026-08-16).** `frank-default-small` serves `qwen3.6-moe:35b-a3b` on port 52625 (swap churn and the unknown-tag incident are recorded above). The remaining NPU content (benchmarks, runbook steps) is still research until a step lands and is recorded. +- **NPU production role (2026-08-16).** `frank-small` serves `qwen3.6-moe:35b-a3b` on port 52625 (swap churn and the unknown-tag incident are recorded above). The remaining NPU content (benchmarks, runbook steps) is still research until a step lands and is recorded. ## Citations diff --git a/serverAppConfigs-docs/LLM/Pipeline Parallelism/Ethernet Bandwidth Math.md b/serverAppConfigs-docs/LLM/Pipeline Parallelism/Ethernet Bandwidth Math.md index 2bb5b93..10b54d9 100644 --- a/serverAppConfigs-docs/LLM/Pipeline Parallelism/Ethernet Bandwidth Math.md +++ b/serverAppConfigs-docs/LLM/Pipeline Parallelism/Ethernet Bandwidth Math.md @@ -26,7 +26,7 @@ conclusions. | Blocks | 65 (45 on worker, 20 on head) | `--tensor-split 0.68,0.32` | | FA layers | 16 total, interval 4 (11 worker / 5 head) | GGUF `full_attention_interval` | | KV per FA layer per token | 3136 B (K q8_0 1088 + V f16 2048) | env file comment, confirmed | -| ubatch | 256 | `UBATCH_SIZE` in `frank-default-large.env` | +| ubatch | 256 | `UBATCH_SIZE` in `frank-large.env` | | MTP verify step positions | 5 (1 + n_max 4) | `SPEC_DRAFT_N_MAX=4` | | Link (old path) | 1 GbE via USB-C adapter on claw | `enx00e04cc2e1e5`, negotiated 1000 Mb/s | | Link (current path) | 2.5 GbE eno1 to eno1 | negotiated 2500 Mb/s both ends | diff --git a/serverAppConfigs-docs/LLM/Pipeline Parallelism/Qwen3.6 27B Spec Methods.md b/serverAppConfigs-docs/LLM/Pipeline Parallelism/Qwen3.6 27B Spec Methods.md index 585143f..ef86eac 100644 --- a/serverAppConfigs-docs/LLM/Pipeline Parallelism/Qwen3.6 27B Spec Methods.md +++ b/serverAppConfigs-docs/LLM/Pipeline Parallelism/Qwen3.6 27B Spec Methods.md @@ -189,7 +189,7 @@ For the 2-node pipeline-parallel split (RTX 3090 24 GB + Strix Halo 96 GB): - **Kept:** Qwen official config.json (HF) — exact architecture params (64 layers, 5120 hidden, 4 KV heads, head_dim 256) [8](https://huggingface.co/Qwen/Qwen3.6-27B/blob/main/config.json) - **Kept:** bartowski/Qwen_Qwen3.6-27B-GGUF — Q8_0 at 29.12 GB, imatrix calibration [2](https://huggingface.co/bartowski/Qwen_Qwen3.6-27B-GGUF) - **Kept:** Alittlehammmer/Qwen3.6-27B-DFlash-GGUF-llama.cpp — DFlash 2B draft GGUF model [4](https://huggingface.co/Alittlehammmer/Qwen3.6-27B-DFlash-GGUF-llama.cpp) -- **Kept:** frank-default-large-benchmark.md — Project spec benchmarks (MTP, DFlash, ngram-mod comparison) [5](../frank-default-large-benchmark.md) +- **Kept:** frank-large-benchmark.md — Project spec benchmarks (MTP, DFlash, ngram-mod comparison) [5](../frank-large-benchmark.md) - **Kept:** a4lg/Qwen3.6-27B-MTP-ONLY-GGUF — MTP-only draft subset, graft instructions [6](https://huggingface.co/a4lg/Qwen3.6-27B-MTP-ONLY-GGUF) - **Kept:** llama.cpp tools/rpc/README.md — RPC backend, weight/KV split, remote host setup [7](https://github.com/ggerganov/llama.cpp/blob/master/tools/rpc/README.md) - **Kept:** Unsloth Qwen3.6-27B-MTP-GGUF — MTP command-line usage for llama.cpp [9](https://huggingface.co/unsloth/Qwen3.6-27B-MTP-GGUF) diff --git a/serverAppConfigs-docs/LLM/Pipeline Parallelism/Qwen3.8 PP Deployment.md b/serverAppConfigs-docs/LLM/Pipeline Parallelism/Qwen3.8 PP Deployment.md index 6765351..e4778c3 100644 --- a/serverAppConfigs-docs/LLM/Pipeline Parallelism/Qwen3.8 PP Deployment.md +++ b/serverAppConfigs-docs/LLM/Pipeline Parallelism/Qwen3.8 PP Deployment.md @@ -11,7 +11,7 @@ morning-of runbook. Research background: ## Production state (2026-08-17: Q6_K, q8_0/f16 KV, split 0.68) -This split is the production `frank-default-large` service. Current +This split is the production `frank-large` service. Current state, verified against the live journal and output smoke tests (2026-08-17, load 02:06): @@ -32,17 +32,17 @@ state, verified against the live journal and output smoke tests Vulkan). - Worker steady state: 23854/24576 MiB used, ~273 MiB free (tight but stable; all allocations are upfront). -- Unit `frank-default-large.service`, launched through - `serve-pp-head.sh` + `frank-default-large.env`. +- Unit `frank-large.service`, launched through + `serve-pp-head.sh` + `frank-large.env`. ## Service enablement (2026-08-17) The PP pair is the only inference service enabled for boot. Both units -(`frank-default-large` on Dankclaw, `frank-pp-worker` on Dankserver) are -enabled. The NPU unit (`frank-default-small` on Dankclaw) and all retired +(`frank-large` on Dankclaw, `frank-pp-worker` on Dankserver) are +enabled. The NPU unit (`frank-small` on Dankclaw) and all retired units are disabled. Restart order: worker first, then head. The Dankserver helper `frank-restart-small.sh` is obsolete (it restarts the removed -`frank-default-small` unit); restart the worker with +`frank-small` unit); restart the worker with `sudo systemctl restart frank-pp-worker`. The Dankclaw helper `frank-restart-large.sh` (sync + cache drop + restart) is correct for the head. `deploy.sh dankserver` is broken until retargeted. See @@ -164,9 +164,9 @@ llama-server b10433 ggml-rpc-server b10433 |------|---------|---------| | `scripts/frank-pp-worker.env` | server | worker tunables (bind, port, device, cache) | | `scripts/serve-pp-worker.sh` | server | runs `ggml-rpc-server` from the b10433 worktree build | -| `scripts/frank-default-large.env` | claw | head tunables (split, ctx, spec, KV, I/O); was `frank-pp-head.env` before the 2026-08-16 rename | +| `scripts/frank-large.env` | claw | head tunables (split, ctx, spec, KV, I/O); was `frank-pp-head.env` before the 2026-08-16 rename | | `scripts/serve-pp-head.sh` | claw | runs `llama-server --rpc ...` (see "Gotchas") | -| `scripts/frank-default-large.service` / `frank-pp-worker.service` | both | optional systemd units (manual install); the head unit was renamed from `frank-pp-head.service` on 2026-08-16 and is symlinked from the repo into `/etc/systemd/system` | +| `scripts/frank-large.service` / `frank-pp-worker.service` | both | optional systemd units (manual install); the head unit was renamed from `frank-pp-head.service` on 2026-08-16 and is symlinked from the repo into `/etc/systemd/system` | | `scripts/pp-test.sh` | any box with ssh to both | test orchestrator (preflight/start/verify/bench/stop-pp/restore) | | `scripts/pp-bench.py` | claw | API driver; reports server-side `print_timing` | @@ -220,7 +220,7 @@ FRANK_SUDO_PW= ./scripts/pp-test.sh stop-pp FRANK_SUDO_PW= ./scripts/pp-test.sh restore ``` -Config variants: edit `scripts/frank-default-large.env` on the claw (git commit + +Config variants: edit `scripts/frank-large.env` on the claw (git commit + pull if the bench runs from the repo), then re-run `start` + `bench`: - No spec baseline: `SPEC_NONE=1` diff --git a/serverAppConfigs-docs/LLM/Pipeline Parallelism/index.md b/serverAppConfigs-docs/LLM/Pipeline Parallelism/index.md index 83f93f0..44ba3de 100644 --- a/serverAppConfigs-docs/LLM/Pipeline Parallelism/index.md +++ b/serverAppConfigs-docs/LLM/Pipeline Parallelism/index.md @@ -76,6 +76,6 @@ graph LR ## See Also - [[DFlash DSpark Speculative Decoding]] -- [[frank-default-small-benchmark]] +- [[frank-small-benchmark]] - [[Dankserver System Specs]] - [[Dankclaw System Specs]] diff --git a/serverAppConfigs-docs/LLM/Running Qwen3.6 27B FP8 on Dankclaw.md b/serverAppConfigs-docs/LLM/Running Qwen3.6 27B FP8 on Dankclaw.md index 0f8c504..09fe265 100644 --- a/serverAppConfigs-docs/LLM/Running Qwen3.6 27B FP8 on Dankclaw.md +++ b/serverAppConfigs-docs/LLM/Running Qwen3.6 27B FP8 on Dankclaw.md @@ -47,7 +47,7 @@ The FP8 variant requires approximately 16-17 GB. ThinkingCap-FP8 requires ~29 GB ## Prerequisites -> **Production note:** Dankclaw's primary service now runs vLLM-ROCm with the Ling-3.0-flash CIRU INT4 model (see `scripts/frank-default-large.service`). This page documents the alternative vLLM FP8 deployment of Qwen3.6-27B. +> **Production note:** Dankclaw's primary service now runs vLLM-ROCm with the Ling-3.0-flash CIRU INT4 model (see `scripts/frank-large.service`). This page documents the alternative vLLM FP8 deployment of Qwen3.6-27B. Install vLLM for ROCm. Version 0.24.0+ is required for Qwen3.6 with speculative decoding: diff --git a/serverAppConfigs-docs/LLM/Running Qwen3.6 35B A3B FP8 on Dankserver.md b/serverAppConfigs-docs/LLM/Running Qwen3.6 35B A3B FP8 on Dankserver.md index d0ce93d..f668910 100644 --- a/serverAppConfigs-docs/LLM/Running Qwen3.6 35B A3B FP8 on Dankserver.md +++ b/serverAppConfigs-docs/LLM/Running Qwen3.6 35B A3B FP8 on Dankserver.md @@ -114,7 +114,7 @@ export HF_HOME=/mnt/entropy/huggingface ### Active Service Conflict -The retired `frank-default-small` service (llama.cpp) used about 22 GB of the 24 GB VRAM. The current PP worker holds ~23.8 GiB. The `vllm-awq-qwen36` (Podman) and `vllm-qwen36` units are disabled. Before starting any research service, verify that the GPU is free: +The retired `frank-small` service (llama.cpp) used about 22 GB of the 24 GB VRAM. The current PP worker holds ~23.8 GiB. The `vllm-awq-qwen36` (Podman) and `vllm-qwen36` units are disabled. Before starting any research service, verify that the GPU is free: ``` nvidia-smi # verify GPU is free diff --git a/serverAppConfigs-docs/LLM/agentionai-fast-imatrix.md b/serverAppConfigs-docs/LLM/agentionai-fast-imatrix.md index 64fc8e4..95f5434 100644 --- a/serverAppConfigs-docs/LLM/agentionai-fast-imatrix.md +++ b/serverAppConfigs-docs/LLM/agentionai-fast-imatrix.md @@ -1,7 +1,7 @@ --- type: reference title: agentionai Qwen3.8-Flash-Next ROCmFP4-FAST imatrix on Dankclaw -description: agentionai/Qwen3.8-Flash-Next-ROCmFP4-FAST-imatrix-GGUF served by the charlie12345/ROCmFPX llama.cpp runtime (build-qwen38). 87.06 GiB Q4_0_ROCMFP4_FAST imatrix (v2 joined PLE layout), own MTP draft head (ROCmFP4-FAST, 2.28 GiB). frank-default-large. +description: agentionai/Qwen3.8-Flash-Next-ROCmFP4-FAST-imatrix-GGUF served by the charlie12345/ROCmFPX llama.cpp runtime (build-qwen38). 87.06 GiB Q4_0_ROCMFP4_FAST imatrix (v2 joined PLE layout), own MTP draft head (ROCmFP4-FAST, 2.28 GiB). frank-large. tags: - llama.cpp - rocm @@ -26,7 +26,7 @@ timestamp: 2026-08-29 > `--flash-attn on` work on the charlie build-qwen38 tree — all still > true for that binary + model pair, which remains the rollback target. -`frank-default-large` (port 7770) served +`frank-large` (port 7770) served `agentionai/Qwen3.8-Flash-Next-ROCmFP4-FAST-imatrix-GGUF` (main, `Qwen3.8-Flash-Next-ROCmFP4-FAST-imatrix-v2.gguf`, the `v2/` joined layout) with the author's own MTP draft head @@ -166,7 +166,7 @@ best: 32.4 t/s, 0.612 acceptance; adaptive p-split measured worse). ## Config files -- Env: `scripts/frank-default-large.env` +- Env: `scripts/frank-large.env` - Serve: `scripts/serve-frank-large.sh` - Chat template: `scripts/chat-template.jinja` (unchanged, Qwen-Sharp) - Fork patch: `scripts/patches/qwen4exp-qsa-f32-mask.patch` (re-apply after @@ -175,10 +175,10 @@ best: 32.4 t/s, 0.612 acceptance; adaptive p-split measured worse). ## Swap procedure ```bash -sudo systemctl stop frank-default-large -# edit scripts/frank-default-large.env + scripts/serve-frank-large.sh, commit, push -# on Dankclaw: git pull --ff-only && scripts/deploy.sh dankclaw --service frank-default-large -sudo systemctl start frank-default-large # or via deploy.sh +sudo systemctl stop frank-large +# edit scripts/frank-large.env + scripts/serve-frank-large.sh, commit, push +# on Dankclaw: git pull --ff-only && scripts/deploy.sh dankclaw --service frank-large +sudo systemctl start frank-large # or via deploy.sh curl http://192.168.0.143:7770/health ``` diff --git a/serverAppConfigs-docs/LLM/ciru-activefpx-promptforge.md b/serverAppConfigs-docs/LLM/ciru-activefpx-promptforge.md index be9323f..0e8a0ee 100644 --- a/serverAppConfigs-docs/LLM/ciru-activefpx-promptforge.md +++ b/serverAppConfigs-docs/LLM/ciru-activefpx-promptforge.md @@ -1,7 +1,7 @@ --- type: reference title: CIRU ActiveFPX PromptForge on Dankclaw -description: jcbtc/Qwen3.8-27B-CIRU-ActiveFPX-PromptForge (v3) served by the CIRU ROCmFPX llama.cpp runtime on the Strix Halo iGPU. Install runbook, ROCm 7.15 toolchain, and the frank-default-large service. +description: jcbtc/Qwen3.8-27B-CIRU-ActiveFPX-PromptForge (v3) served by the CIRU ROCmFPX llama.cpp runtime on the Strix Halo iGPU. Install runbook, ROCm 7.15 toolchain, and the frank-large service. tags: - llama.cpp - rocm @@ -14,12 +14,12 @@ timestamp: 2026-08-22 # CIRU ActiveFPX PromptForge on Dankclaw -> **Active 2026-08-22.** `frank-default-large` serves this v3 model again +> **Active 2026-08-22.** `frank-large` serves this v3 model again > after a same-day Kairic Edge IU4 experiment was reverted (operator > decision). Commit `c60156f` restored the v3 script pair. See > [[kairic-edge]] for the retired experiment reference. -`frank-default-large` (port 7770, moved from 52625 on 2026-08-22) serves +`frank-large` (port 7770, moved from 52625 on 2026-08-22) serves `jcbtc/Qwen3.8-27B-CIRU-ActiveFPX-PromptForge` **v3** through the CIRU ROCmFPX llama.cpp runtime. This replaced the retired vLLM service that previously occupied the slot. The v2 deployment moved to v3 on 2026-08-21. @@ -135,7 +135,7 @@ graph TD C --> D[Build llama-server] D --> E[Verify --list-devices shows gfx1151] E --> F[Download v3 GGUF + FFN/GDN/Output-K8 + mmproj] - F --> G[Deploy frank-default-large] + F --> G[Deploy frank-large] G --> H[Health check + chat completion] ``` @@ -150,8 +150,8 @@ against the model card before the service restart. ## Service -- Unit: `frank-default-large.service`, port 7770 -- Script: `scripts/serve-frank-large.sh`, env `scripts/frank-default-large.env` +- Unit: `frank-large.service`, port 7770 +- Script: `scripts/serve-frank-large.sh`, env `scripts/frank-large.env` - The script exports the ROCm 7.15 SDK libraries in `LD_LIBRARY_PATH` before the system ROCm. `ROCM_PATH` points at the devel SDK. diff --git a/serverAppConfigs-docs/LLM/dankserver-vram-growth.md b/serverAppConfigs-docs/LLM/dankserver-vram-growth.md index 289da13..544f247 100644 --- a/serverAppConfigs-docs/LLM/dankserver-vram-growth.md +++ b/serverAppConfigs-docs/LLM/dankserver-vram-growth.md @@ -5,7 +5,7 @@ --- type: reference title: Dankserver VRAM and RAM Growth Under Load -description: Investigation of the recurring cuBLAS crash on frank-default-small. What grows, what does not, and what to do next. +description: Investigation of the recurring cuBLAS crash on frank-small. What grows, what does not, and what to do next. tags: - dankserver - llamacpp @@ -18,7 +18,7 @@ tags: # Dankserver VRAM and RAM Growth Under Load This page records the investigation of the recurring cuBLAS crash on -`frank-default-small` (llama.cpp, RTX 3090 24 GiB). The service aborts +`frank-small` (llama.cpp, RTX 3090 24 GiB). The service aborts with `CUDA error: an unsupported value or parameter was passed to the function` in `cublasSgemm_v2` at `ggml-cuda.cu:1541` during `update_slots` -> `decode` -> `process_ubatch`. It crashed on 2026-08-13 @@ -116,7 +116,7 @@ Verified 2026-08-14 after deploy: flash attention enabled, warmup clean, decode ## Mitigation Options -The documentation for the benchmark ([[frank-default-small-benchmark]]) +The documentation for the benchmark ([[frank-small-benchmark]]) prescribes the first option for this crash class. None of these change the model. @@ -135,6 +135,6 @@ PR #25649 (slot checkpoints freed on prompt clear, merged), issue #26119 ## See Also -- [[frank-default-small-benchmark]] +- [[frank-small-benchmark]] - [[Dankserver System Specs]] - [[deployment]] \ No newline at end of file diff --git a/serverAppConfigs-docs/LLM/dealign-ornith-crack.md b/serverAppConfigs-docs/LLM/dealign-ornith-crack.md index 793d17c..bc5397e 100644 --- a/serverAppConfigs-docs/LLM/dealign-ornith-crack.md +++ b/serverAppConfigs-docs/LLM/dealign-ornith-crack.md @@ -1,7 +1,7 @@ --- type: reference title: dealign Ornith-1.5-35B-A3B CRACK on Dankserver -description: dealignai/Ornith-1.5-35B-A3B-UNCENSORED (CRACK Q6_K) served by upstream llama.cpp on the RTX 3090. MoE model with ngram-mod speculative decoding; selected expert weights offloaded to CPU with an explicit --override-tensor. frank-default-small. +description: dealignai/Ornith-1.5-35B-A3B-UNCENSORED (CRACK Q6_K) served by upstream llama.cpp on the RTX 3090. MoE model with ngram-mod speculative decoding; selected expert weights offloaded to CPU with an explicit --override-tensor. frank-small. tags: - llamacpp - cuda @@ -14,12 +14,12 @@ timestamp: 2026-08-24 # dealign Ornith-1.5-35B-A3B CRACK on Dankserver -> **Active 2026-08-25.** `frank-default-small` serves this model. It +> **Active 2026-08-25.** `frank-small` serves this model. It > replaced the CRACK Q8_0 file on the same upstream llama.cpp binary (b10121). > The Q6_K file was downloaded from the model repository and validated with > `llama-gguf` before installation. -`frank-default-small` (port 7770) serves +`frank-small` (port 7770) serves `Ornith-1.5-35B-A3B-CRACK-Q6_K.gguf` from `dealignai` on Hugging Face. It is a **MoE** model (256 experts, 8 active) with a hybrid GatedDeltaNet (SSM) + attention architecture, abliterated (uncensored). The GGUF also contains a diff --git a/serverAppConfigs-docs/LLM/deployment.md b/serverAppConfigs-docs/LLM/deployment.md index 07e70c8..9fa0b8f 100644 --- a/serverAppConfigs-docs/LLM/deployment.md +++ b/serverAppConfigs-docs/LLM/deployment.md @@ -19,8 +19,9 @@ SearXNG, Caddy, or another container service does **not** restart inference. | Target | Host | Service | Port | |---|---|---|---:| -| Dankserver | `dank@dankserver` | `frank-default-small` | 7770 | -| Dankclaw | `dank@dankclaw` | `frank-default-large` | 7770 | +| Dankserver | `dank@dankserver` | `frank-small` | 7770 | +| Dankclaw | `dank@dankclaw` | `frank-large` | 7770 | +| Dankclaw | `dank@dankclaw` | `frank-npu` (FLM on the XDNA2 NPU) | 7771 | ## Scoped workflow @@ -38,34 +39,39 @@ graph LR Run the unified deployer from the repository root: ```bash -./scripts/deploy.sh dankserver --service frank-default-small -./scripts/deploy.sh dankclaw --service frank-default-large +./scripts/deploy.sh dankserver --service frank-small +./scripts/deploy.sh dankclaw --service frank-large ./scripts/deploy.sh dankclaw --dry-run ``` Without `--service`, `scripts/deploy-plan.py` maps changed files to the service on the selected host. The following files select the corresponding service: -- `scripts/frank-default-small.env`, `frank-default-small.service`, and - `serve-frank-small.sh` select `frank-default-small` on Dankserver. -- `scripts/frank-default-large.env`, `frank-default-large.service`, and - `serve-frank-large.sh` select `frank-default-large` on Dankclaw. +- `scripts/frank-small.env`, `frank-small.service`, and + `serve-frank-small.sh` select `frank-small` on Dankserver. +- `scripts/frank-large.env`, `frank-large.service`, and + `serve-frank-large.sh` select `frank-large` on Dankclaw. +- `scripts/frank-npu.env`, `frank-npu.service`, + and `serve-frank-npu.sh` select `frank-npu` + on Dankclaw. - `scripts/chat-template.jinja` selects the LLM on the selected host only. - Documentation, tests, deployment tooling, and unrelated container changes do not select either inference service. The target-side `scripts/deploy-remote.sh` relinks the selected unit into `/etc/systemd/system/`, reloads systemd, enables it, restarts it, and waits for -`http://127.0.0.1:7770/health`. The wait budget is 20 minutes because cold model -loads can be slow. A failed handler does not advance its per-service state. +that service's health endpoint (`http://127.0.0.1:7770/health` for the two +inference services; `/v1/version` for the NPU sight+sound endpoint — FLM has no +`/health` route). The wait budget is 20 minutes because cold model loads can be +slow. A failed handler does not advance its per-service state. ## Unit and artifact paths Both units point into the stable target checkout: ```text -/home/dank/serverAppConfigs/scripts/frank-default-small.service -/home/dank/serverAppConfigs/scripts/frank-default-large.service +/home/dank/serverAppConfigs/scripts/frank-small.service +/home/dank/serverAppConfigs/scripts/frank-large.service ``` The unit files and serve scripts validate their model/runtime artifacts before @@ -74,8 +80,8 @@ the unit absolute paths and the deployment tests in the same change. ## NPU unit -`frank-default-npu` is an inactive, historical Dankclaw endpoint. It is -relinked only when explicitly selected with `--service frank-default-npu`; the +`frank-npu` is an inactive, historical Dankclaw endpoint. It is +relinked only when explicitly selected with `--service frank-npu`; the large-model handler never restarts it. This is intentional: the NPU is not part of the active inference path and should not be disturbed by a large-model change. @@ -99,16 +105,16 @@ change in that service's inputs. If the LLM handler fails after the target pull: -1. Inspect `journalctl -u frank-default-small -n 200` or - `journalctl -u frank-default-large -n 200`. +1. Inspect `journalctl -u frank-small -n 200` or + `journalctl -u frank-large -n 200`. 2. Confirm the model files, custom runtime binary, and chat template are readable by `dank`. 3. Retry only the affected service: ```bash - ./scripts/deploy.sh dankserver --service frank-default-small + ./scripts/deploy.sh dankserver --service frank-small # or - ./scripts/deploy.sh dankclaw --service frank-default-large + ./scripts/deploy.sh dankclaw --service frank-large ``` 4. Verify the matching health endpoint before declaring recovery. diff --git a/serverAppConfigs-docs/LLM/dflash2-large-vulkan.md b/serverAppConfigs-docs/LLM/dflash2-large-vulkan.md index f7cbf23..9402baf 100644 --- a/serverAppConfigs-docs/LLM/dflash2-large-vulkan.md +++ b/serverAppConfigs-docs/LLM/dflash2-large-vulkan.md @@ -1,6 +1,6 @@ --- type: reference -title: DFlash2 on Dankclaw (frank-default-large) +title: DFlash2 on Dankclaw (frank-large) description: ARCHIVED - unsloth Qwen3.8-27B-UD-Q8_K_XL served by upstream llama.cpp PR #27342 with a z-lab DFlash2 drafter on the Vulkan backend. Retired 2026-08-21 for speed; kept as a runbook. tags: - llama.cpp @@ -13,14 +13,14 @@ tags: timestamp: 2026-08-21 --- -# DFlash2 on Dankclaw (frank-default-large) — ARCHIVED +# DFlash2 on Dankclaw (frank-large) — ARCHIVED > **Archived 2026-08-21.** This DFlash2 Vulkan deployment was retired the > same day it shipped because it was slower than the CIRU runtime it -> replaced. `frank-default-large` is back on CIRU. This page stays as the +> replaced. `frank-large` is back on CIRU. This page stays as the > runbook and provenance for the DFlash2 attempt. -`frank-default-large` (port 52625) briefly served +`frank-large` (port 52625) briefly served `unsloth/Qwen3.8-27B-UD-Q8_K_XL` with a DFlash2 drafter from z-lab. The runtime was upstream llama.cpp PR #27342 built with `GGML_VULKAN=ON`. @@ -114,14 +114,14 @@ graph TD C --> D[Build llama-server] D --> E[Verify Vulkan0 device] E --> F[Add DFlash2 drafter] - F --> G[Swap frank-default-large] + F --> G[Swap frank-large] G --> H[Health check + completion] ``` ## Service -- Unit: `frank-default-large.service`, port 52625 -- Script: `scripts/serve-frank-large.sh`, env `scripts/frank-default-large.env` +- Unit: `frank-large.service`, port 52625 +- Script: `scripts/serve-frank-large.sh`, env `scripts/frank-large.env` - Binary: `/home/dank/llama.cpp-dflash2/build-dflash2/bin/llama-server` ### Launch profile diff --git a/serverAppConfigs-docs/LLM/eemin-rocmi4-mtp.md b/serverAppConfigs-docs/LLM/eemin-rocmi4-mtp.md index 653bac2..38f3307 100644 --- a/serverAppConfigs-docs/LLM/eemin-rocmi4-mtp.md +++ b/serverAppConfigs-docs/LLM/eemin-rocmi4-mtp.md @@ -1,7 +1,7 @@ --- type: reference title: caf-eemin Qwen3.8-27B ROCmI4 embedded MTP on Dankclaw -description: caf-eemin/Qwen3.8-27B-ROCmI4-MTP-GGUF (Q4_0_ROCMI4, embedded NextN/MTP head) served by the charlie12345/ROCmFPX llama.cpp runtime (ROCmI4 W4A4) on the Strix Halo iGPU. frank-default-large. +description: caf-eemin/Qwen3.8-27B-ROCmI4-MTP-GGUF (Q4_0_ROCMI4, embedded NextN/MTP head) served by the charlie12345/ROCmFPX llama.cpp runtime (ROCmI4 W4A4) on the Strix Halo iGPU. frank-large. tags: - llama.cpp - rocm @@ -15,12 +15,12 @@ timestamp: 2026-08-25 # caf-eemin Qwen3.8-27B ROCmI4 embedded MTP on Dankclaw -> **Active 2026-08-25.** `frank-default-large` serves this model. It replaced +> **Active 2026-08-25.** `frank-large` serves this model. It replaced > the kingjones777 ROCmFP4 STRIX MTP payload on the same port and the same > Strix Halo iGPU, running the new charlie12345/ROCmFPX ROCmI4 W4A4 build. See > [[kingjones-strix-mtp]] for the retired page. -`frank-default-large` (port 7770) serves +`frank-large` (port 7770) serves `cafonz/Qwen3.8-27B-ROCmI4-MTP-GGUF` (published under the public `eemin` namespace) from the **charlie12345/ROCmFPX** llama.cpp fork built with the opt-in `ROCmI4 W4A4` path. The model is `Q4_0_ROCMI4`: signed four-bit @@ -127,8 +127,8 @@ path's greedy decisions; it does not remove the W4A4 activation approximation. ### Service -- Unit: `frank-default-large.service`, port 7770 -- Script: `scripts/serve-frank-large.sh`, env `scripts/frank-default-large.env` +- Unit: `frank-large.service`, port 7770 +- Script: `scripts/serve-frank-large.sh`, env `scripts/frank-large.env` ## Tuning MTP @@ -142,14 +142,14 @@ Decode throughput depends on the ubatch (per-eval token batch). Run the sweep on 8k contexts, 512 → 4096 in steps of 512, with a fixed batch: ``` -sudo systemctl stop frank-default-large +sudo systemctl stop frank-large ./scripts/bench-ubatch.sh -sudo systemctl start frank-default-large +sudo systemctl start frank-large ``` -The script stops `frank-default-large` for a clean GPU, boots one server +The script stops `frank-large` for a clean GPU, boots one server instance per ubatch on a scratch port, reads authoritative `print_timing` tok/s, -and restarts the service. See [[frank-default-large-benchmark]]. +and restarts the service. See [[frank-large-benchmark]]. ## Known Issues @@ -183,4 +183,4 @@ The ubatch sweep above gives the production ubatch choice. - [[kingjones-strix-mtp]] — the retired ROCmFP4 predecessor on this slot - [[ciru-activefpx-promptforge]] — the retired v3 CIRU PromptForge page - [[Dankclaw System Specs]] — the box -- [[frank-default-large-benchmark]] — backend/spec benchmark history +- [[frank-large-benchmark]] — backend/spec benchmark history diff --git a/serverAppConfigs-docs/LLM/frank-large-benchmark.md b/serverAppConfigs-docs/LLM/frank-large-benchmark.md index f711565..6b28e5e 100644 --- a/serverAppConfigs-docs/LLM/frank-large-benchmark.md +++ b/serverAppConfigs-docs/LLM/frank-large-benchmark.md @@ -2,10 +2,10 @@ > See [frank-redo-2026-08-17.md](frank-redo-2026-08-17.md) and > [deployment.md](deployment.md) for the active configuration. -# frank-default-large — Backend and Spec Benchmark +# frank-large — Backend and Spec Benchmark This page records the benchmarks that chose the runtime for -`frank-default-large` on Dankclaw. Every number came from the live +`frank-large` on Dankclaw. Every number came from the live llama.cpp build on that machine (upstream, b10133+). ## Summary diff --git a/serverAppConfigs-docs/LLM/frank-npu.md b/serverAppConfigs-docs/LLM/frank-npu.md index b449652..da7792f 100644 --- a/serverAppConfigs-docs/LLM/frank-npu.md +++ b/serverAppConfigs-docs/LLM/frank-npu.md @@ -1,6 +1,6 @@ --- type: configuration -title: frank-default-sightsound Runbook +title: frank-npu Runbook description: FastFlowLM (FLM) NPU sight+sound endpoint on Dankclaw — XDNA2 NPU serving Qwen3.8 Distilled Heretic vision+text pack on port 7771, including the IOMMU/SVA root cause that took it down at first deploy. tags: - flm @@ -8,17 +8,17 @@ tags: - xdna2 - npu - dankclaw - - frank-default-sightsound + - frank-npu timestamp: 2026-09-01 --- -# frank-default-sightsound — FLM NPU sight+sound Runbook +# frank-npu — FLM NPU sight+sound Runbook -`frank-default-sightsound` is the third inference endpoint on Dankclaw: a +`frank-npu` is the third inference endpoint on Dankclaw: a FastFlowLM (FLM) v1.0.1 server (`/usr/bin/flm`, dpkg package `fastflowlm`) running on the **XDNA2 NPU** (50 TOPS). It serves *sight* (vision) — which the iGPU llama.cpp fleet ([[kingjones-strix-rocmfp4]], -`frank-default-large`) does not do. The model-selection tradeoff: the only +`frank-large`) does not do. The model-selection tradeoff: the only NPU2 pack family on this box with BOTH a vision and an audio tower is the Gemma4 E4B IT pack; the uncensored candidate (`qwythos:9b`, 8.94 GB, 262k ctx) is text-only and fails the hard modality requirement, so this endpoint trades @@ -29,9 +29,9 @@ is text-only and fails the hard modality requirement, so this endpoint trades | Field | Value | |-------|-------| | Runtime | FLM v1.0.1 (`/usr/bin/flm`, dpkg `fastflowlm`) on the XDNA2 NPU | -| Service | `frank-default-sightsound.service` (systemd system unit, `User=dank`, `Restart=on-failure`, `RestartSec=10`, `LimitMEMLOCK=infinity`) | -| Files | `scripts/frank-default-sightsound.env`, `scripts/serve-frank-default-sightsound.sh`, `scripts/frank-default-sightsound.service` | -| Deploy | `scripts/deploy.sh dankclaw --service frank-default-sightsound` (relink + daemon-reload + enable + restart; health gate polls `/v1/version`, 300 s cap — FLM has **no `/health` route**) | +| Service | `frank-npu.service` (systemd system unit, `User=dank`, `Restart=on-failure`, `RestartSec=10`, `LimitMEMLOCK=infinity`) | +| Files | `scripts/frank-npu.env`, `scripts/serve-frank-npu.sh`, `scripts/frank-npu.service` | +| Deploy | `scripts/deploy.sh dankclaw --service frank-npu` (relink + daemon-reload + enable + restart; health gate polls `/v1/version`, 300 s cap — FLM has **no `/health` route**) | | Port | `7771` on `0.0.0.0` (52625/52626 left free for ad-hoc `flm serve` experiments) | | Power mode | `FLM_PMODE=turbo` — no other tenant uses the NPU on this host (the large model runs on the iGPU), so the top power mode costs no neighbour anything; drop to `performance` if iGPU power-budget contention ever shows | | Context | `FLM_CTX_LEN=131072 (128K; verified max on this box; native context length.) | @@ -57,8 +57,8 @@ clients choose, send requests with the desired `model` field. **To swap the active model** (changes what the service loads at start): ``` -sed -i 's/^FLM_MODEL=.*/FLM_MODEL=/' scripts/frank-default-sightsound.env -./scripts/deploy.sh dankclaw --service frank-default-sightsound +sed -i 's/^FLM_MODEL=.*/FLM_MODEL=/' scripts/frank-npu.env +./scripts/deploy.sh dankclaw --service frank-npu ``` **To switch per-request** (service stays loaded, client sends the tag): @@ -119,7 +119,7 @@ chain, all live-verified on the host: 3. Fix: replace `iommu=off` with **`iommu=pt`** in `GRUB_CMDLINE_LINUX_DEFAULT` on `/etc/default/grub`, `update-grub`, reboot. Passthrough mode keeps the iGPU default domain identity-mapped (zero DMA-translation overhead for - `frank-default-large`) while enabling IOMMU hardware + PASID, which is what + `frank-large`) while enabling IOMMU hardware + PASID, which is what the NPU driver's SVA bind requires — PASID domains are paged regardless of the default-domain type. 4. Post-boot verification: `/sys/kernel/iommu_groups/` populated (30 groups), diff --git a/serverAppConfigs-docs/LLM/frank-redo-2026-08-17.md b/serverAppConfigs-docs/LLM/frank-redo-2026-08-17.md index d2e2c06..62e450a 100644 --- a/serverAppConfigs-docs/LLM/frank-redo-2026-08-17.md +++ b/serverAppConfigs-docs/LLM/frank-redo-2026-08-17.md @@ -8,15 +8,15 @@ The old scripts moved to `old/scripts/` in this repository. | Service | Host | Runtime | Model | Port | |---------|------|---------|-------|------| -| frank-default-large | Dankserver | llama.cpp (patched FastMTP) | HauhauCS Qwen3.8-27B-Uncensored-Aggressive IQ4_XS | 7770 | -| frank-default-small | Dankclaw | vLLM ROCm | nameistoken Qwen3.6-35B-A3B Quark W8A8 INT8 | 52625 | +| frank-large | Dankserver | llama.cpp (patched FastMTP) | HauhauCS Qwen3.8-27B-Uncensored-Aggressive IQ4_XS | 7770 | +| frank-small | Dankclaw | vLLM ROCm | nameistoken Qwen3.6-35B-A3B Quark W8A8 INT8 | 52625 | The RTX 3090 runs the whole 27B model standalone. No RPC worker, no tensor split, no NPU. ## Models -### frank-default-large — HauhauCS/Qwen3.8-27B-Uncensored-HauhauCS-Aggressive-MTP-GGUF:IQ4_XS +### frank-large — HauhauCS/Qwen3.8-27B-Uncensored-HauhauCS-Aggressive-MTP-GGUF:IQ4_XS - Base: Qwen3.8-27B (dense 27B, 64 layers: 48 GatedDeltaNet + 16 gated-attention, hidden 5120, 24 Q heads / 4 KV heads, head dim 256, @@ -31,7 +31,7 @@ tensor split, no NPU. `--spec-draft-ngl all`, `--spec-draft-p-min 0`) then ngram-mod fallback (48/64/24). -### frank-default-small — nameistoken/Qwen3.6-35B-A3B-Quark-W8A8-INT8 +### frank-small — nameistoken/Qwen3.6-35B-A3B-Quark-W8A8-INT8 - Base: Qwen3.6-35B-A3B (hybrid MoE, 256 experts top-8, ~3B active, 40 layers: 10 blocks of 3 DeltaNet + 1 Attention, native 262144 ctx). @@ -46,7 +46,7 @@ tensor split, no NPU. instead of the Qwen3 XML structure). The Quark quant follows the format cleanly; swapped in the evening of 2026-08-17. -## Context Math (frank-default-large, RTX 3090) +## Context Math (frank-large, RTX 3090) KV per token: 16 attention layers x 4 KV heads x 256 dim. K q8_0 = 1088 B/token, V f16 = 2048 B/token, total 50176 B/token. @@ -63,11 +63,11 @@ Budget (MiB): 24576 total - 14982 weights - 861 draft - 1024 fixed Production choice: **131072 (128K)** — the maximum that keeps about 1.4 GiB headroom for checkpoints. Lower `CTX_SIZE` in -`scripts/frank-default-large.env` to 122880 for ~1.8 GiB headroom. +`scripts/frank-large.env` to 122880 for ~1.8 GiB headroom. ## Install Runbook -### Dankserver (frank-default-large) +### Dankserver (frank-large) 1. Stop the old worker: `sudo systemctl stop frank-pp-worker`. 2. Download the model and draft to `/home/dank/models/hauhaucs-qwen38/`. @@ -87,17 +87,17 @@ Production choice: **131072 (128K)** — the maximum that keeps about measured 95 t/s vs 1300+ t/s at 8K on the 3090). 4. Symlink the unit, reload, enable, restart: ``` - sudo ln -sf /home/dank/vLLM/scripts/frank-default-large.service /etc/systemd/system/ - sudo systemctl daemon-reload && sudo systemctl enable frank-default-large - sudo systemctl restart frank-default-large + sudo ln -sf /home/dank/vLLM/scripts/frank-large.service /etc/systemd/system/ + sudo systemctl daemon-reload && sudo systemctl enable frank-large + sudo systemctl restart frank-large ``` 5. Verify: `curl -sf http://127.0.0.1:7770/health` and a chat completion. 6. Confirm VRAM headroom with `nvidia-smi`. -### Dankclaw (frank-default-small) +### Dankclaw (frank-small) -1. Stop the old services: `sudo systemctl stop frank-default-large - frank-default-small` (retired PP head and NPU endpoint). +1. Stop the old services: `sudo systemctl stop frank-large + frank-small` (retired PP head and NPU endpoint). 2. Install uv and create the venv: ``` curl -LsSf https://astral.sh/uv/install.sh | sh @@ -122,9 +122,9 @@ Production choice: **131072 (128K)** — the maximum that keeps about vision encoder falls back to torch SDPA and engine init OOMs. 5. Symlink the unit, reload, enable, restart: ``` - sudo ln -sf /home/dank/vllmScripts/scripts/frank-default-small.service /etc/systemd/system/ - sudo systemctl daemon-reload && sudo systemctl enable frank-default-small - sudo systemctl restart frank-default-small + sudo ln -sf /home/dank/vllmScripts/scripts/frank-small.service /etc/systemd/system/ + sudo systemctl daemon-reload && sudo systemctl enable frank-small + sudo systemctl restart frank-small ``` 6. Verify: `curl -sf http://127.0.0.1:52625/health` and a chat completion. @@ -150,7 +150,7 @@ on gfx1151; newer vLLM releases may already include it. Three changes landed after the initial deployment: -### 1. Tool calling on frank-default-small (HTTP 400 fix) +### 1. Tool calling on frank-small (HTTP 400 fix) Clients (pi) send `tool_choice: "auto"`. vLLM rejects it with HTTP 400 unless the server enables tool calling. Fixes applied: @@ -175,7 +175,7 @@ model behavior, which motivated the swap. ### 2. Model swap: Avesed INT8 W8A8 -> Quark W8A8 INT8 -`frank-default-small` now serves +`frank-small` now serves `nameistoken/Qwen3.6-35B-A3B-Quark-W8A8-INT8` (AMD Quark 0.11.1, ~35 GB, vLLM-native expert layout). The Avesed compressed-tensors quant's Qwen3-XML tool fidelity was poor. Verified with the Quark model: plain diff --git a/serverAppConfigs-docs/LLM/frank-small-benchmark.md b/serverAppConfigs-docs/LLM/frank-small-benchmark.md index 21c699e..695f93e 100644 --- a/serverAppConfigs-docs/LLM/frank-small-benchmark.md +++ b/serverAppConfigs-docs/LLM/frank-small-benchmark.md @@ -1,6 +1,6 @@ --- type: reference -title: frank-default-small Benchmark — ncmoe and Batch Tuning +title: frank-small Benchmark — ncmoe and Batch Tuning description: llama-bench sweep of MoE CPU offload (ncmoe) and batch/ubatch on the RTX 3090 for Qwen3.6-35B-A3B Q6_K_P. tags: - benchmark @@ -10,11 +10,11 @@ tags: - dankserver --- -# frank-default-small Benchmark — ncmoe and Batch/Ubatch Tuning +# frank-small Benchmark — ncmoe and Batch/Ubatch Tuning This page records a llama-bench sweep on Dankserver (RTX 3090, 24 GiB) for the HauhauCS Qwen3.6-35B-A3B Q6_K_P model. The sweep decided the final -`--n-cpu-moe` and `--ubatch-size` values for `frank-default-small`. +`--n-cpu-moe` and `--ubatch-size` values for `frank-small`. Run date: 2026-08-13. Build: llama.cpp `555881ebc` (10121). CUDA, 7 threads, `--cache-type-k q8_0 --cache-type-v f16`, `--fit-target 0` (KV auto-sized to @@ -105,7 +105,7 @@ service runs 700416 cells (13,680 MiB). ## Chosen State -> **Live drift (2026-08-22 audit):** the deployed `frank-default-small` now runs `--n-cpu-moe 38`, `--batch-size 4096`, `--ubatch-size 2048` (ncmoe raised from 36 for stability; batch lowered). The values below are the original benchmark recommendation. +> **Live drift (2026-08-22 audit):** the deployed `frank-small` now runs `--n-cpu-moe 38`, `--batch-size 4096`, `--ubatch-size 2048` (ncmoe raised from 36 for stability; batch lowered). The values below are the original benchmark recommendation. Prefill speed is the priority, so the state keeps the top prefill tier and moves one expert layer to CPU for stability: diff --git a/serverAppConfigs-docs/LLM/freetoken-benchmark-sweep.md b/serverAppConfigs-docs/LLM/freetoken-benchmark-sweep.md index 8676da4..b89b775 100644 --- a/serverAppConfigs-docs/LLM/freetoken-benchmark-sweep.md +++ b/serverAppConfigs-docs/LLM/freetoken-benchmark-sweep.md @@ -6,7 +6,7 @@ tags: - freetoken - benchmark - dankserver - - frank-default-small + - frank-small - qwen3.6 timestamp: 2026-09-02 --- @@ -90,5 +90,5 @@ Tiel-Coder finetune. ## See Also -- [[freetoken-frank-default-small]] — production runbook +- [[freetoken-frank-small]] — production runbook - [[dealign-ornith-crack]] — the prior llama.cpp deployment (retired) \ No newline at end of file diff --git a/serverAppConfigs-docs/LLM/freetoken-frank-small.md b/serverAppConfigs-docs/LLM/freetoken-frank-small.md index 8a29d15..3473796 100644 --- a/serverAppConfigs-docs/LLM/freetoken-frank-small.md +++ b/serverAppConfigs-docs/LLM/freetoken-frank-small.md @@ -1,20 +1,20 @@ --- type: configuration -title: FreeToken frank-default-small Runbook -description: FreeToken v0.1.2 serving batsclamp/Huihui-Qwen3.6-35B-A3B-abliterated-FP8 as frank-default-small on Dankserver (RTX 3090). +title: FreeToken frank-small Runbook +description: FreeToken v0.1.2 serving batsclamp/Huihui-Qwen3.6-35B-A3B-abliterated-FP8 as frank-small on Dankserver (RTX 3090). tags: - freetoken - dankserver - - frank-default-small + - frank-small - qwen3.6 - moe - fp8 timestamp: 2026-08-30 --- -# FreeToken frank-default-small Runbook +# FreeToken frank-small Runbook -The `frank-default-small` service on Dankserver is served by +The `frank-small` service on Dankserver is served by **FreeToken v0.1.2** — an edge-native MoE serving engine that keeps expert weights in host RAM with an LRU GPU cache. Model history on this runtime: official `Qwen/Qwen3.6-35B-A3B-FP8` (since 2026-09-02) → @@ -130,8 +130,8 @@ modelopt block-fp8 remains the only FP8 path that loads. | File | Purpose | |------|---------| | `scripts/serve-frank-small.sh` | Serve script (launches `ft serve`) | -| `scripts/frank-default-small.env` | Tunables (model path, pool sizes) | -| `scripts/frank-default-small.service` | Systemd unit | +| `scripts/frank-small.env` | Tunables (model path, pool sizes) | +| `scripts/frank-small.service` | Systemd unit | ## Limitations @@ -150,7 +150,7 @@ modelopt block-fp8 remains the only FP8 path that loads. - **`model` field is required** in `/v1/chat/completions` bodies — FreeToken rejects requests without it with a 422 (`Field required`), unlike llama.cpp's server which defaults to the loaded model. Send - `"model": "frank-default-small"`. + `"model": "frank-small"`. - Load on this swap took well under the old llama.cpp numbers: weights → experts (parallel build) → CUDA graph capture → Uvicorn in ~2 minutes; the 2026-08-30 swap verified ~40 tok/s decode on a diff --git a/serverAppConfigs-docs/LLM/ikllama-ornith-dankserver.md b/serverAppConfigs-docs/LLM/ikllama-ornith-dankserver.md index 3586b86..0f1dd4f 100644 --- a/serverAppConfigs-docs/LLM/ikllama-ornith-dankserver.md +++ b/serverAppConfigs-docs/LLM/ikllama-ornith-dankserver.md @@ -1,7 +1,7 @@ --- type: reference title: ik_llama.cpp on Dankserver (Ornith Q8_0) -description: ikawrakow/ik_llama.cpp replaces upstream llama.cpp for frank-default-small on the RTX 3090. Q8_0 model, KV K default f16 / V q6_0 with Hadamard on V only (iq5_k is not a KV-cache type in this build; q8_KV crashes on this arch), split-mode none, speculative decoding disabled, 3 parallel slots x 163840 ctx, the Qwen-Sharp template rendered with --jinja, and explicit CPU-expert offload. Includes the mandatory CUDA/IQK FA_ALL_QUANTS build flags. +description: ikawrakow/ik_llama.cpp replaces upstream llama.cpp for frank-small on the RTX 3090. Q8_0 model, KV K default f16 / V q6_0 with Hadamard on V only (iq5_k is not a KV-cache type in this build; q8_KV crashes on this arch), split-mode none, speculative decoding disabled, 3 parallel slots x 163840 ctx, the Qwen-Sharp template rendered with --jinja, and explicit CPU-expert offload. Includes the mandatory CUDA/IQK FA_ALL_QUANTS build flags. tags: - ikllama - llamacpp @@ -16,7 +16,7 @@ timestamp: 2026-08-26 # ik_llama.cpp on Dankserver (Ornith-1.5-35B-A3B CRACK) -> **Active 2026-08-26.** `frank-default-small` switched from upstream +> **Active 2026-08-26.** `frank-small` switched from upstream > llama.cpp (b10121) to `ikawrakow/ik_llama.cpp` (commit `b166e269`) on the > RTX 3090. This page documents the build, the mandatory FA build flags, and > the MoE / CPU-offload runtime arguments. @@ -101,8 +101,8 @@ a hard compile error. ## Runtime configuration -Files: `scripts/serve-frank-small.sh`, `scripts/frank-default-small.env`, -`scripts/frank-default-small.service` in the repo. The service just calls +Files: `scripts/serve-frank-small.sh`, `scripts/frank-small.env`, +`scripts/frank-small.service` in the repo. The service just calls the serve script; the env file holds all tunables. ### KV cache: K default f16 / V q6_0 + Hadamard (V only) @@ -241,7 +241,7 @@ apply. The previous runtime `upstream llama.cpp b10121` and its binary (`/home/dank/llama.cpp/build/bin/llama-server`) are **left untouched**. To rollback to the old stack, change `LLAMA_SERVER=` in -`scripts/frank-default-small.env` back to that path and +`scripts/frank-small.env` back to that path and `CACHE_TYPE_K/V` back to `f16` with Hadamard off, and re-enable the ngram spec / `--spec-type` flags. The model file is not changed either way. diff --git a/serverAppConfigs-docs/LLM/index.md b/serverAppConfigs-docs/LLM/index.md index 894c1e1..692b9cb 100644 --- a/serverAppConfigs-docs/LLM/index.md +++ b/serverAppConfigs-docs/LLM/index.md @@ -1,9 +1,9 @@ # LLM Fleet — Knowledge Base Documentation for the LLM inference fleet on two local machines -(2026-08-30): FreeToken v0.1.2 on Dankserver (frank-default-small, +(2026-08-30): FreeToken v0.1.2 on Dankserver (frank-small, Huihui-Qwen3.6-35B-A3B-abliterated-FP8) and kingjones30/ROCmFPX -llama.cpp on Dankclaw (frank-default-large, kingjones777 +llama.cpp on Dankclaw (frank-large, kingjones777 Qwen3.8-Flash-Next ROCmFP4-STRIX). Both services run the Qwen-Sharp chat template. > 2026-08-22: the former `vllmScripts` repository is merged into the @@ -18,7 +18,7 @@ graph LR subgraph Dankserver[NVIDIA Dankserver - Ubuntu 26.04] A[RTX 3090 24GB + 60GB RAM] B2[FreeToken v0.1.2 -frank-default-small, port 7770] +frank-small, port 7770] C[Huihui-Qwen3.6-35B-A3B-abliterated-FP8 block-fp8, 20% MoE residency, 453k KV / 4 streams] A --> B2 --> C @@ -27,7 +27,7 @@ block-fp8, 20% MoE residency, 453k KV / 4 streams] subgraph Dankclaw[AMD Strix Halo - Ubuntu 26.04] E2[gfx1151 iGPU 64 GiB unified memory] E[kingjones30/ROCmFPX build -frank-default-large, port 7770] +frank-large, port 7770] F[kingjones777 Qwen3.8-Flash-Next ROCmFP4-STRIX, 401k ctx / 2 slots, mmap PLE] E2 --> E --> F @@ -46,18 +46,18 @@ ROCmFP4-STRIX, 401k ctx / 2 slots, mmap PLE] ## Active Deployment -- [[freetoken-frank-default-small]] — the active frank-default-small +- [[freetoken-frank-small]] — the active frank-small runbook: FreeToken v0.1.2 serving batsclamp/Huihui-Qwen3.6-35B-A3B- abliterated-FP8 on Dankserver (swapped 2026-08-30; same format/pools) - [[freetoken-benchmark-sweep]] — KV pool vs decode speed sweep (bs1/bs3/bs4/bs6, 8k–700k KV) on Dankserver RTX 3090 - [[deployment]] — deploy and update process for both servers - [[frank-redo-2026-08-17]] — the 2026-08-17 topology change -- [[kingjones-strix-rocmfp4]] — ACTIVE frank-default-large runbook: +- [[kingjones-strix-rocmfp4]] — ACTIVE frank-large runbook: kingjones777/Qwen3.8-Flash-Next-ROCmFP4-STRIX-GGUF, 177B params (56B MoE + 51.2B PLE), single 113.47 GiB GGUF, on the card's pinned kingjones30/ROCmFPX fork (swapped 2026-08-30) -- [[agentionai-fast-imatrix]] — retired frank-default-large runbook: +- [[agentionai-fast-imatrix]] — retired frank-large runbook: agentionai/Qwen3.8-Flash-Next-ROCmFP4-FAST-imatrix (87.06 GiB Q4_0_ROCMFP4_FAST imatrix, v2 joined PLE) on build-qwen38 (2026-08-29 → 2026-08-30); rollback binary + payload retained @@ -66,9 +66,9 @@ ROCmFP4-STRIX, 401k ctx / 2 slots, mmap PLE] - [[eemin-rocmi4-mtp]] — the former caf-eemin Qwen3.8-27B embedded-MTP model on Dankclaw (retired) - [[dealign-ornith-crack]] — the retired Ornith-1.5-35B-A3B CRACK model on - Dankserver (frank-default-small, retired 2026-09-02) + Dankserver (frank-small, retired 2026-09-02) - [[ikllama-ornith-dankserver]] — the retired ik_llama.cpp runtime for - frank-default-small (2026-08-26): q8_0 + Hadamard KV cache, + frank-small (2026-08-26): q8_0 + Hadamard KV cache, split-mode none (single-GPU), mandatory FA_ALL_QUANTS build flags - [[kingjones-strix-mtp]] — the former Q6 AGENT runbook (restored 2026-09-01 after Q8_0 failure, then superseded by the STRIX deployment on 2026-08-27) @@ -76,9 +76,10 @@ ROCmFP4-STRIX, 401k ctx / 2 slots, mmap PLE] on Dankclaw (superseded 2026-08-24 by the kingjones ROCmFP4 model) - [[kairic-edge]] — the retired Kairic Edge IU4 experiment (deployed and reverted 2026-08-22) -- [[Dankserver System Specs]] — the RTX 3090 box (frank-default-small) -- [[Dankclaw System Specs]] — the CIRU ROCmFPX box (frank-default-large) -- [[frank-default-sightsound]] — ACTIVE FLM NPU sight+sound runbook on +- [[Dankserver System Specs]] — the RTX 3090 box (frank-small) +- [[Dankclaw System Specs]] — the Strix Halo gfx1151 box (frank-large, + served on the pinned kingjones30/ROCmFPX llama.cpp fork since 2026-08-30) +- [[frank-npu]] — ACTIVE FLM NPU sight+sound runbook on Dankclaw: Gemma4 E4B vision+audio pack on the XDNA2 NPU (FLM v1.0.1, port 7771, whole-registry serving, per-request model routing), incl. the IOMMU/SVA root cause and the `iommu=pt` fix behind its first-deploy crash @@ -101,8 +102,10 @@ ROCmFP4-STRIX, 401k ctx / 2 slots, mmap PLE] - [[VLLM Overview]] — installation, CLI, API, architecture, quantization, parallelism - [[VLLM Index]] — quick reference with commands, endpoints, and parameter table - [[Running Qwen3.6 35B A3B FP8 on Dankserver]] — Qwen3.6-35B-A3B hardware - notes and sizing (the historical family; frank-default-small now serves - Ornith-1.5-35B-A3B, see [[dealign-ornith-crack]]) + notes and sizing (this architecture family is what frank-small + serves today in the Huihui abliterated FP8 variant — see + [[freetoken-frank-small]]; the Ornith-1.5-35B-A3B CRACK checkpoint + that preceded it is archived at [[dealign-ornith-crack]]) ## Memory Management @@ -115,7 +118,7 @@ ROCmFP4-STRIX, 401k ctx / 2 slots, mmap PLE] - [[Qwen3.8 PP Deployment]] — the retired pipeline-parallel head + worker - [[qwen3.8-spec-matrix]] — Qwen3.8-27B spec history (superseded by FastMTP) - [[FastFlowLM NPU Inference]] — the retired FastFlowLM NPU endpoint -- [[frank-default-large-benchmark]] — backend/spec benchmark behind the old head +- [[frank-large-benchmark]] — backend/spec benchmark behind the old head - [[dankserver-vram-growth]] — VRAM/RAM growth behind the retired cuBLAS crash - [[DFlash DSpark Speculative Decoding]] — retired DFlash/DSpark drafting - [[Quantization by Hardware Architecture]] — which quant format fits which GPU/CPU @@ -134,7 +137,7 @@ ROCmFP4-STRIX, 401k ctx / 2 slots, mmap PLE] ## Related - [Project knowledge base](../index.md) — the Podman app stacks on the same - two hosts. OpenWebUI consumes the `:7770` endpoint on Dankserver. The - Gitea instance on Dankclaw hosts this repository. + two hosts. OpenWebUI (Dankclaw) consumes the on-host `frank-large` + endpoint at `:7770`. The Gitea instance on Dankclaw hosts this repository. - [Deployment Flow](../Architecture/Deployment%20Flow.md) — the service-scoped git-based deploy with inference isolation \ No newline at end of file diff --git a/serverAppConfigs-docs/LLM/kairic-edge.md b/serverAppConfigs-docs/LLM/kairic-edge.md index eeee46c..a46b1d5 100644 --- a/serverAppConfigs-docs/LLM/kairic-edge.md +++ b/serverAppConfigs-docs/LLM/kairic-edge.md @@ -17,10 +17,10 @@ timestamp: 2026-08-22 > **Retired 2026-08-22.** This experiment was deployed, benchmarks were > collected, and the service reverted to v3 the same day (operator -> decision). `frank-default-large` serves v3 again. This page is kept as +> decision). `frank-large` serves v3 again. This page is kept as > the retired experiment's build runbook and reference. -`frank-default-large` (port 52625) briefly served +`frank-large` (port 52625) briefly served `jcbtc/Qwen3.8-27B-IU4-Kairic-Edge` through the Kairic Edge CIRU ROCmFPX llama.cpp runtime. The runtime routes qualified prompt and multi-token verification shapes through the RDNA 3.5 native @@ -215,7 +215,7 @@ service restart confirms the fresh tree, then it is a deletion candidate The service runs the pinned runner profile plus the local chat deviations below. Tunables live in -`scripts/frank-default-large.env`; flags in `scripts/serve-frank-large.sh`. +`scripts/frank-large.env`; flags in `scripts/serve-frank-large.sh`. See [[deployment]] for the update process. | Setting | Value | Origin | @@ -301,7 +301,7 @@ ubatches do not. Production runs the runner's qualified 2048/512. The v3 payload and binary stay on the machine for rollback. -1. Stop the service: `sudo systemctl stop frank-default-large` +1. Stop the service: `sudo systemctl stop frank-large` 2. Restore the v3 scripts: `git revert 4c43839 7aee1df 40d50fe` (or checkout the script pair from commit `132e147`) diff --git a/serverAppConfigs-docs/LLM/kingjones-q8agent-rocmfpx.md b/serverAppConfigs-docs/LLM/kingjones-q8agent-rocmfpx.md index 04fbe1c..01d98cc 100644 --- a/serverAppConfigs-docs/LLM/kingjones-q8agent-rocmfpx.md +++ b/serverAppConfigs-docs/LLM/kingjones-q8agent-rocmfpx.md @@ -1,11 +1,11 @@ -# frank-default-large: kingjones Qwen3.8-27B-ROCmFPX-Q8_0-AGENT +# frank-large: kingjones Qwen3.8-27B-ROCmFPX-Q8_0-AGENT **Status:** Deployed on Dankclaw (since 2026-08-25). Serving is **BLOCKED by the `set_rows` build bug** — the model loads but crashes in `ggml_compute_forward_set_rows` before it can serve. All config goals are met; a build fix is required for the model to run. -**Alias:** `frank-default-large`, port **7770**. +**Alias:** `frank-large`, port **7770**. The large service serves the kingjones `Qwen3.8-27B-ROCmFPX-Q8_0-AGENT` GGUF from `/home/dank/models/kingjones-Qwen3.8-27B-ROCMFPX-Q8_0-AGENT/` with a @@ -26,7 +26,7 @@ fit in the lifted **114 GiB TTM/GTT** budget (see the 114 GiB change in | Reasoning | on, `deepseek`, budget `-1`, `--reasoning-format none` | | Chat template | Sharp (repo-tracked), `enable_thinking` + `preserve_thinking` on | | Host path | `/home/dank/models/kingjones-Qwen3.8-27B-ROCMFPX-Q8_0-AGENT/` | -| Tunables | `scripts/frank-default-large.env` | +| Tunables | `scripts/frank-large.env` | | Serve script | `scripts/serve-frank-large.sh` | ## Serving status: the `set_rows` build bug (blocks serving) @@ -107,7 +107,7 @@ dl mtp-Qwen3.8-27B-Q4_0.gguf ``` The serve script checks each artifact is present and readable before launch -(`scripts/frank-default-large.env` -> the four `MODEL_*` files plus the chat +(`scripts/frank-large.env` -> the four `MODEL_*` files plus the chat template). A missing file fails the artifact check with `missing or unreadable required artifact`. @@ -116,7 +116,7 @@ unreadable required artifact`. `scripts/serve-frank-large.sh` builds the `llama-server` call from the env: ``` -/dev/llama-server -m
--alias frank-default-large +/dev/llama-server -m
--alias frank-large --host 0.0.0.0 --port 7770 --jinja -dev ROCm0 -ngl 999 -np 1 -c 262144 -b 512 -ub 512 -fa on @@ -197,7 +197,7 @@ and a 28 GB + 262k-KV load stalls. The GTT page-limit change is per the ## Env tunables -`scripts/frank-default-large.env`. Serving: `CTX_SIZE=262144`, +`scripts/frank-large.env`. Serving: `CTX_SIZE=262144`, `PARALLEL=1`, `BATCH_SIZE=512`, `UBATCH_SIZE=512`, `NUM_THREADS=16`, `THREAD_BATCH=32`, `CACHE_TYPE_K=f16`, `CACHE_TYPE_V=turbo4`, `CTX_CHECKPOINTS=32`, `CACHE_RAM=8192`. Reasoning: `REASONING=on`, diff --git a/serverAppConfigs-docs/LLM/kingjones-strix-mtp.md b/serverAppConfigs-docs/LLM/kingjones-strix-mtp.md index d5c927c..66e2369 100644 --- a/serverAppConfigs-docs/LLM/kingjones-strix-mtp.md +++ b/serverAppConfigs-docs/LLM/kingjones-strix-mtp.md @@ -1,7 +1,7 @@ --- type: reference title: kingjones Qwen3.8-27B ROCmFP4 STRIX MTP on Dankclaw -description: kingjones777/Qwen3.8-27B-Uncensored-ROCmFP4-STRIX-MTP served by the CIRU ROCmFPX llama.cpp runtime on the Strix Halo iGPU. Dense model with a standalone MTP Q4_0 draft head. frank-default-large. +description: kingjones777/Qwen3.8-27B-Uncensored-ROCmFP4-STRIX-MTP served by the CIRU ROCmFPX llama.cpp runtime on the Strix Halo iGPU. Dense model with a standalone MTP Q4_0 draft head. frank-large. tags: - llama.cpp - rocm @@ -16,13 +16,13 @@ timestamp: 2026-08-24 # kingjones Qwen3.8-27B ROCmFP4 STRIX MTP on Dankclaw > **Active again 2026-09-01.** The kingjones ROCmFP4 STRIX MTP payload is -> restored as `frank-default-large` after the Q8_0 AGENT experiment. The Q8_0 +> restored as `frank-large` after the Q8_0 AGENT experiment. The Q8_0 > model was retired because it crashed before serving. The Q6 AGENT model, > standalone MTP draft, Q8 projector, and PromptForge runtime are now active. > This page documents the active model and its runbook. -`frank-default-large` (port 7770) serves +`frank-large` (port 7770) serves `Qwen3.8-27B-Uncensored-ROCmFP4-STRIX-MTP` from `kingjones777` on Hugging Face. It is a **dense** Qwen3.8-27B, abliterated (uncensored), quantized to the ROCmFP4 Q6 AGENT format (ftype 114). The MTP speculative head ships as diff --git a/serverAppConfigs-docs/LLM/kingjones-strix-rocmfp4.md b/serverAppConfigs-docs/LLM/kingjones-strix-rocmfp4.md index 4fcb009..9a1d853 100644 --- a/serverAppConfigs-docs/LLM/kingjones-strix-rocmfp4.md +++ b/serverAppConfigs-docs/LLM/kingjones-strix-rocmfp4.md @@ -1,7 +1,7 @@ --- type: reference title: kingjones Qwen3.8-Flash-Next ROCmFP4 STRIX on Dankclaw -description: ACTIVE frank-default-large runbook. kingjones777/Qwen3.8-Flash-Next-ROCmFP4-STRIX-GGUF served by the card's pinned kingjones30/ROCmFPX fork. 177B params (56B MoE + 51.2B PLE streamed via mmap), single 113.47 GiB GGUF, 401408 ctx x 2 slots. +description: ACTIVE frank-large runbook. kingjones777/Qwen3.8-Flash-Next-ROCmFP4-STRIX-GGUF served by the card's pinned kingjones30/ROCmFPX fork. 177B params (56B MoE + 51.2B PLE streamed via mmap), single 113.47 GiB GGUF, 401408 ctx x 2 slots. tags: - llama.cpp - rocm @@ -23,10 +23,10 @@ timestamp: 2026-08-30 > decoding is OFF (the card ships no spec flags; the Flash-Next MTP heads > do not load on this loader family — see MTP Draft Head). -`frank-default-large` (port 7770) serves +`frank-large` (port 7770) serves `Qwen3.8-Flash-Next-Q4_0-ROCmFP4-STRIX.gguf` (single file, 113.47 GiB) from `/home/dank/models/kingjones-Qwen3.8-Flash-Next-ROCmFP4-STRIX/` -via `scripts/serve-frank-large.sh` + `scripts/frank-default-large.env` +via `scripts/serve-frank-large.sh` + `scripts/frank-large.env` and the Qwen-Sharp chat template. ## Model Architecture @@ -178,7 +178,7 @@ cmake --build build --target llama-server llama-quantize -j16 ## Serving Profile -Deployed args (`scripts/frank-default-large.env` — our validated +Deployed args (`scripts/frank-large.env` — our validated profile, unchanged from the FAST deployment except the binary and model): ``` @@ -272,9 +272,9 @@ The file is 113.47 GiB. Allow ~20-30 minutes for download depending on network. 1. Build the runtime (see Runtime build) BEFORE touching the service. 2. Point the model file's directory at the canonical path (a plain `mv` — never delete a 113 GiB payload to re-fetch it). -3. Edit `scripts/frank-default-large.env` (+ serve script defaults) via +3. Edit `scripts/frank-large.env` (+ serve script defaults) via git: commit, push, `./scripts/deploy.sh dankclaw --service - frank-default-large`. + frank-large`. 4. Verify health: `curl http://192.168.0.143:7770/health` and a real `/v1/chat/completions` probe. @@ -284,7 +284,7 @@ binary and the agentionai payload remain on disk. ### Config files -- Env: `scripts/frank-default-large.env` +- Env: `scripts/frank-large.env` - Serve: `scripts/serve-frank-large.sh` - Chat template: `scripts/chat-template.jinja` diff --git a/serverAppConfigs-docs/LLM/ling-3.0-flash-trial.md b/serverAppConfigs-docs/LLM/ling-3.0-flash-trial.md index 3c8774a..8509065 100644 --- a/serverAppConfigs-docs/LLM/ling-3.0-flash-trial.md +++ b/serverAppConfigs-docs/LLM/ling-3.0-flash-trial.md @@ -1,10 +1,6 @@ # Ling-3.0-flash Q6_K Trial on Dankclaw -> **RETIRED 2026-08-17.** The `frank-large-ling` unit is disabled under the boot policy. `frank-default-large` now runs the Qwen3.8-27B PP head, not the Qwen3.6-27B config described in the (obsolete) switch-back section below. - -This page records the Ling-3.0-flash trial that temporarily replaced -`frank-default-large` on Dankclaw. It replaces the Qwen3.6-27B service on -port 7770 under the same API alias. +> **RETIRED 2026-08-17.** The `frank-large-ling` unit is disabled under the boot policy. At this page's retirement date `frank-large` ran the Qwen3.8-27B PP head (since superseded by the STRIX deployment — see [[kingjones-strix-rocmfp4]]), not the Qwen3.6-27B config described in the (obsolete) switch-back section below. ## Status @@ -73,22 +69,22 @@ point varies (385-1588 tokens). Single streams never freeze. `SPEC_TYPE=none`, `PARALLEL=2`. All concurrent streams complete (EOS). Speed cost: ~10-13 t/s under contention vs ~28-32 t/s single-stream with MTP. Fallback chain if spec-off regresses: A) `PARALLEL=1` keep MTP, -B) switch back to Qwen3.6-27B (frank-default-large, MTP n_max 3). +B) switch back to Qwen3.6-27B (frank-large, MTP n_max 3). ## Files - `scripts/frank-large-ling.service` - systemd unit. - `scripts/serve-ling-flash.sh` - serve script (fork binary, Vulkan, draft-mtp). -- `scripts/frank-default-large.ling.env` - tunables. +- `scripts/frank-large.ling.env` - tunables. Passwordless management is installed: `/usr/local/sbin/frank-restart-ling.sh` and `/etc/sudoers.d/frank-ling`. ## Switch Back (obsolete) -The switch-back commands below are obsolete. `frank-default-large` now -runs the Qwen3.8-27B pipeline-parallel head. To restore a Ling trial, +The switch-back commands below are obsolete. At retirement time +`frank-large` ran the Qwen3.8-27B pipeline-parallel head. To restore a Ling trial, re-enable `frank-large-ling` from the repo unit (`scripts/frank-large-ling.service`) and serve script (`scripts/serve-ling-flash.sh`), then start it on a non-conflicting port. @@ -107,6 +103,6 @@ re-enable `frank-large-ling` from the repo unit ## See Also -- [[frank-default-large-benchmark]] +- [[frank-large-benchmark]] - [[DFlash DSpark Speculative Decoding]] - [[deployment]] diff --git a/serverAppConfigs-docs/LLM/ling-3.0-flash-vllm-plan.md b/serverAppConfigs-docs/LLM/ling-3.0-flash-vllm-plan.md index 1baa9d8..dff960c 100644 --- a/serverAppConfigs-docs/LLM/ling-3.0-flash-vllm-plan.md +++ b/serverAppConfigs-docs/LLM/ling-3.0-flash-vllm-plan.md @@ -6,5 +6,5 @@ Dankclaw. The deployment never shipped. The actual Ling work used the llama.cpp Q6_K fork trial instead: [[ling-3.0-flash-trial]]. The trial service (`frank-large-ling`) is retired and disabled under the -boot policy (2026-08-17). `frank-default-large` is the Qwen3.8-27B PP +boot policy (2026-08-17). `frank-large` is the Qwen3.8-27B PP head, not the Ling path. See git history for the full decision table. diff --git a/serverAppConfigs-docs/LLM/qwen3.8-spec-matrix.md b/serverAppConfigs-docs/LLM/qwen3.8-spec-matrix.md index 654842d..050ad7d 100644 --- a/serverAppConfigs-docs/LLM/qwen3.8-spec-matrix.md +++ b/serverAppConfigs-docs/LLM/qwen3.8-spec-matrix.md @@ -5,7 +5,7 @@ # Qwen3.8-27B Speculative-Decoding Matrix This page records the speculative-decoding benchmark history and the -production tuning for the Qwen3.8-27B service (`frank-default-large`), +production tuning for the Qwen3.8-27B service (`frank-large`), now a pipeline-parallel head with a Dankserver worker. ## Production state (2026-08-17: Q6_K, q8_0/f16 KV, split 0.68) @@ -145,7 +145,7 @@ that is the long-context attention penalty, not a spec artifact. ## Production Configuration -The live tunables live in `scripts/frank-default-large.env` (head) and +The live tunables live in `scripts/frank-large.env` (head) and `scripts/frank-pp-worker.env` (worker) in this repo. The Production state section at the top of this page records the current values: Q6_K model + standalone MTP draft, split 0.68/0.32, 262144 ctx, PARALLEL=1, @@ -153,6 +153,6 @@ q8_0/f16 KV. ## See Also -- [[frank-default-large-benchmark]] +- [[frank-large-benchmark]] - [[ling-3.0-flash-trial]] - [[deployment]] diff --git a/serverAppConfigs-docs/LLM/qwen3.8-strix-optimizations.md b/serverAppConfigs-docs/LLM/qwen3.8-strix-optimizations.md index ef2eb3f..4051bfd 100644 --- a/serverAppConfigs-docs/LLM/qwen3.8-strix-optimizations.md +++ b/serverAppConfigs-docs/LLM/qwen3.8-strix-optimizations.md @@ -7,7 +7,7 @@ and the test matrix planned for 2026-08-16 morning. Related pages: - [Speculative-decoding matrix](qwen3.8-spec-matrix.md) -- [Backend and spec benchmark](frank-default-large-benchmark.md) +- [Backend and spec benchmark](frank-large-benchmark.md) - [Dankclaw Improvements](Dankclaw%20Improvements.md) (OS-level items) - [Pipeline Parallelism: Qwen3.8 PP Deployment](Pipeline%20Parallelism/Qwen3.8%20PP%20Deployment.md) @@ -58,7 +58,7 @@ Consequences of the hybrid design: ## Current production state (baseline) -`frank-default-large` (Dankclaw, Vulkan0, 2026-08-15): +`frank-large` (Dankclaw, Vulkan0, 2026-08-15): - Model: UD-Q8_K_XL, 31.5 GB, bundled MTP head. - `--spec-default` (ngram-mod) with draft-mtp first in the chain. @@ -225,7 +225,7 @@ tensor cache warm). | E | A with n_max 3 and 5 | n_max curve on the split | | F | A, plain Q8_0 model file | same-bit A/B | | G | PP default proportional split (no `--tensor-split`) | confirms the 20/80 handicap | -| Ref | production frank-default-large (Vulkan, 2 slots) | the bar to beat | +| Ref | production frank-large (Vulkan, 2 slots) | the bar to beat | Per config: `pp-test.sh bench 4` (4k prompt / 256 out) and `bench 16` (16k / 256). Report: decode t/s (server print_timing), prefill t/s, MTP @@ -245,5 +245,5 @@ production @16k) with the same 8-bit model. `-dio` for RPC). - llama.cpp b10433 source: `src/llama.cpp` (device selection), `common/speculative.cpp` (MTP/ngram-mod), `ggml/src/ggml-rpc` (protocol). -- Local benchmarks: [frank-default-large-benchmark](frank-default-large-benchmark.md), +- Local benchmarks: [frank-large-benchmark](frank-large-benchmark.md), [qwen3.8-spec-matrix](qwen3.8-spec-matrix.md). diff --git a/serverAppConfigs-docs/LLM/ubatch-benchmark-large.md b/serverAppConfigs-docs/LLM/ubatch-benchmark-large.md index 712195d..d5fe213 100644 --- a/serverAppConfigs-docs/LLM/ubatch-benchmark-large.md +++ b/serverAppConfigs-docs/LLM/ubatch-benchmark-large.md @@ -1,6 +1,6 @@ --- type: benchmark plan -title: frank-default-large ubatch sweep +title: frank-large ubatch sweep description: Standardized ubatch sweep for the active kingjones Qwen3.8 ROCmFPX deployment. tags: - llama.cpp @@ -10,9 +10,9 @@ tags: timestamp: 2026-09-01 --- -# frank-default-large ubatch sweep +# frank-large ubatch sweep -This benchmark uses the active `frank-default-large` model on Dankclaw with +This benchmark uses the active `frank-large` model on Dankclaw with `llama-bench`. It does not use `llama-server`, HTTP requests, or server-log scraping. Stop the production service before running it and start the service again afterward. @@ -29,9 +29,9 @@ Each point runs three 128-token repetitions by default. Run on Dankclaw from the repository checkout: ```bash -sudo systemctl stop frank-default-large +sudo systemctl stop frank-large ./scripts/bench-ubatch.sh -sudo systemctl start frank-default-large +sudo systemctl start frank-large ``` The script uses the active Q6 AGENT model, an 8K prompt workload, equal diff --git a/serverAppConfigs-docs/Research/Service Research Brief.md b/serverAppConfigs-docs/Research/Service Research Brief.md index 9ada33c..ae16c32 100644 --- a/serverAppConfigs-docs/Research/Service Research Brief.md +++ b/serverAppConfigs-docs/Research/Service Research Brief.md @@ -1,6 +1,6 @@ # Service Research Brief -Consolidated research from the `frank-default-small` research subagents (2026-08-14) plus the pi agent knowledge base. This is the source material behind the per-service docs pages. +Consolidated research from the `frank-small` research subagents (2026-08-14) plus the pi agent knowledge base. This is the source material behind the per-service docs pages. ## Method diff --git a/serverAppConfigs-docs/index.md b/serverAppConfigs-docs/index.md index b94047f..c91f4d9 100644 --- a/serverAppConfigs-docs/index.md +++ b/serverAppConfigs-docs/index.md @@ -51,8 +51,9 @@ covers both workloads). - [[readarr]] — ebook/audiobook management - [[prowlarr]] — indexer management - [[qbittorrent]] — torrent download client -- [[Plex]] — native systemd media server on Dankserver (not a container) -- [[Tautulli]] — Plex statistics and notifications, snap-packaged +- [[Plex]] — media server on Dankserver (lscr.io/linuxserver/plex container via + quadlet; CPU decode only — no GPU passthrough) +- [[Tautulli]] — Plex statistics and notifications (v2.18.1-ls242, quadlet unit) - [[mariadb]] — RomM database backend - [[redis]] — RomM cache/queue backend @@ -62,7 +63,7 @@ covers both workloads). - [[SearXNG Providers]] — unblocking Google & other upstream engines behind the VPN - [[Gluetun]] — the VPN tunnel container - [[Valkey]] — SearXNG cache and limiter store -- [[ComfyUI]] — node-based AI image generation (CPU) +- [[ComfyUI]] — node-based AI image generation (ROCm GPU, gfx1151 build) - [[OpenWebUI]] — chat UI for local LLMs - [[Hermes]] — the Nous Research agent - [[Hermes-Dashboard]] — the Hermes web management UI (config, keys, sessions) @@ -112,35 +113,38 @@ The LLM inference fleet on the two hosts. Full index: - [[deployment]] — unified deploy and update process for both servers - [[frank-redo-2026-08-17]] — the 2026-08-17 topology change -- [[freetoken-frank-default-small]] — the active frank-default-small runbook: FreeToken v0.1.2 serving Qwen3.6-35B-A3B-FP8 on Dankserver (2026-09-02) +- [[freetoken-frank-small]] — the active frank-small runbook: FreeToken v0.1.2 serving Qwen3.6-35B-A3B-FP8 on Dankserver (2026-09-02) - [[freetoken-benchmark-sweep]] — KV pool vs decode speed sweep (bs1/bs3/bs4/bs6, 8k–700k KV) on Dankserver RTX 3090 -- [[kingjones-strix-mtp]] — the active kingjones Qwen3.8-27B ROCmFP4 STRIX MTP model on Dankclaw (restored 2026-09-01) -- [[agentionai-fast-imatrix]] — the ACTIVE frank-default-large runbook: +- [[kingjones-strix-mtp]] — the Qwen3.8-27B-Q6_0 ROCmFPX AGENT era with the + standalone MTP draft (Dankclaw, 2026-08-25 → 2026-08-29; historical) +- [[agentionai-fast-imatrix]] — the retired frank-large runbook: agentionai/Qwen3.8-Flash-Next-ROCmFP4-FAST-imatrix (87.06 GiB, - Q4_0_ROCMFP4_FAST) + own MTP draft head, build-qwen38 (2026-08-29) -- [[kingjones-strix-rocmfp4]] — retired frank-default-large runbook: - kingjones777/Qwen3.8-Flash-Next-ROCmFP4-STRIX-GGUF (177B params, 113.47 GiB) + Q4_0_ROCMFP4_FAST) + own MTP draft, build-qwen38 (retired 2026-08-30; + rollback record) +- [[kingjones-strix-rocmfp4]] — the ACTIVE frank-large runbook since + 2026-08-30: kingjones777/Qwen3.8-Flash-Next-ROCmFP4-STRIX-GGUF (177B params, + 113.47 GiB) on the card's pinned kingjones30/ROCmFPX build - [[kingjones-q8agent-rocmfpx]] — the retired Q8_0-AGENT investigation and `set_rows` failure - [[eemin-rocmi4-mtp]] — the former caf-eemin Qwen3.8-27B ROCmI4 embedded-MTP model on Dankclaw - [[ciru-activefpx-promptforge]] — the RETIRED v3 CIRU PromptForge runtime on Dankclaw (superseded 2026-08-24) - [[kingjones-strix-mtp]] — the kingjones Qwen3.8-27B ROCmFP4 STRIX MTP model on Dankclaw (active) - [[dealign-ornith-crack]] — the retired Ornith-1.5-35B-A3B CRACK model on Dankserver (retired 2026-09-02) -- [[ikllama-ornith-dankserver]] — the retired ik_llama.cpp runtime for frank-default-small (q8_0 + Hadamard KV cache, split-mode none; 2026-08-26) +- [[ikllama-ornith-dankserver]] — the retired ik_llama.cpp runtime for frank-small (q8_0 + Hadamard KV cache, split-mode none; 2026-08-26) - [[kairic-edge]] — the retired Kairic Edge IU4 experiment (2026-08-22) - [[dflash2-large-vulkan]] — the retired DFlash2 Vulkan deployment (2026-08-21) - [[Dankserver System Specs]] — the RTX 3090 box hardware -- [[Dankclaw System Specs]] — the CIRU ROCmFPX box hardware -- [[Dankclaw Improvements]] — host-level changes on the CIRU box -- [[frank-default-sightsound]] — ACTIVE FLM NPU sight+sound runbook on Dankclaw: +- [[Dankclaw System Specs]] — the Strix Halo gfx1151 box (frank-large) +- [[Dankclaw Improvements]] — host-level changes on the Strix Halo box +- [[frank-npu]] — ACTIVE FLM NPU sight+sound runbook on Dankclaw: Gemma4 E4B vision+audio pack on the XDNA2 NPU, port 7771; whole local registry served on one port with per-request model routing; includes the IOMMU/SVA root cause and the `iommu=pt` fix behind its first-deploy crash ### Benchmarks and Sizing -- [[frank-default-large-benchmark]] — backend/spec benchmark behind the old head +- [[frank-large-benchmark]] — backend/spec benchmark behind the old head - [[ubatch-benchmark-large]] — active-model llama-bench ubatch sweep plan and results -- [[frank-default-small-benchmark]] — the small-model benchmark suite +- [[frank-small-benchmark]] — the small-model benchmark suite - [[Running Qwen3.6 35B A3B FP8 on Dankserver]] — Qwen3.6-35B-A3B hardware notes - [[Running Qwen3.6 27B FP8 on Dankclaw]] — Qwen3.6-27B sizing on the iGPU - [[qwen3.8-strix-optimizations]] — Strix Halo tuning notes diff --git a/serverAppConfigs-docs/log.md b/serverAppConfigs-docs/log.md index f764843..67b0ba4 100644 --- a/serverAppConfigs-docs/log.md +++ b/serverAppConfigs-docs/log.md @@ -11,6 +11,41 @@ timestamp: 2026-09-14 # Bundle Change Log +## 2026-09-03 — full fact-check sweep of the docs tree (docs-only, deploy no-op) +- Scope: every page under `/serverAppConfigs-docs/` re-verified against live + hosts (read-only SSH), quadlet unit files, and the Caddyfile; surgical edits + only — no pages created, renamed, or deleted. Per the deploy planner, a + docs-only change is a deploy no-op. +- Dankserver core rewritten to live quadlet facts: the *arr stack + qBittorrent + + gluetun run on **FrankBook-Pro** (units installed to + `/home/core/.config/containers/systemd/` via the frankbook-pro deploy + handler; `PUID=0/PGID=0`, data roots `/Volumes/COMPLETE/-data:/config`; + qB pinned `4.6.7` sharing gluetun's netns with 8080 + 6881 published on the + gluetun unit; readarr pinned `amd64-1.0.980`; no vhosts — direct IP:port, + exempt by construction from the guard chain). Jellyfin, Plex, RomM (8085→8080 + guarded), Calibre-Web (`0.6.27-ls397` + universal-calibre mod; no standalone + calibre-server), mariadb/redis/Tautulli/Entropy verified against live units. +- Caddy guard chain documented to the live mechanism end-to-end: Anubis :8923 → + internal :8016 → post-auth :8017 routing; guarded vhosts (search, grafana, + prometheus, loki, seerr) route post-auth to container-name upstreams; + exemptions named by construction reason (auth/IdP itself, gitea smart-HTTP, + ai→:3005 own auth, hermes/hermesadmin internal-only via DNS absence, pihole + basicauth edge → :8083). +- `Gitea.md`: data roots + secrets corrected to the live unit paths + (`/home/dank/Containers/gitea/{data,postgres,env}`); UID gotcha corrected — + the units carry no `User=`/UserNS override, so container uid 1000 is literally + host uid 1000 (no subuid offset for these containers). +- Dedupe: `Prowlarr.md`/`prowlarr.md` collapsed into one canonical lowercase + page via rename (git history retains both versions; index link unchanged). +- LLM docs: archive pages (`DFlash DSpark Speculative Decoding`, + `ling-3.0-flash-trial`) reworded from current-tense to dated historical + framing with pointers to the active runbook [[kingjones-strix-rocmfp4]]; + LLM `index.md` + `deployment.md` fleet tables and health-gate text updated to + the 2026-08-30 fleet state (STRIX on the pinned ROCmFPX fork; Huihui + abliterated FP8 on FreeToken; sightsound = FLM v1.0.1 on XDNA2, port 7771, + health `/v1/version` — FLM has no `/health` route). +- Suite green after the sweep: `./tests/run.sh` → 233 pass / 0 fail, including + the docs-completeness seam that requires every page to stay index-linked. ## 2026-09-01 (late) — FrankBook-Pro stack completed: tunnel live, qB wired into the arrs - WireGuard credentials provisioned (second Proton config, server `PA-12`, endpoint `51.179.177.2:51820`) → `/home/core/Containers/gluetun/env` @@ -95,9 +130,9 @@ timestamp: 2026-09-14 rules), [[Jellyfin]] gained the LDAP-Auth plugin section. Docs-only commit → deploy no-op. -## 2026-09-01 — frank-default-small: two compressed-tensors FP8 swaps fail to load; Huihui restored -- `/scripts/frank-default-small.env`, `/scripts/serve-frank-small.sh`, - `/scripts/frank-default-small.service` (`af6cd72` → `34ab6b4` → reverted +## 2026-09-01 — frank-small: two compressed-tensors FP8 swaps fail to load; Huihui restored +- `/scripts/frank-small.env`, `/scripts/serve-frank-small.sh`, + `/scripts/frank-small.service` (`af6cd72` → `34ab6b4` → reverted in `4d5bea4`) — attempted model swaps on FreeToken v0.1.2, both live-verified as loader failures and reverted the same day to the Huihui FP8 checkpoint: @@ -114,7 +149,7 @@ timestamp: 2026-09-14 - Both failed cleanly at load (37 GB fits RAM — no swap-thrash, no outage); service was back on Huihui within the hour and re-verified with a real completion (reasoning parses; `17*23 → 391`, natural stop). -- `/serverAppConfigs-docs/LLM/freetoken-frank-default-small.md` — quant +- `/serverAppConfigs-docs/LLM/freetoken-frank-small.md` — quant matrix updated: modelopt block-fp8 is the ONLY FP8 path that loads; both compressed-tensors shapes documented with their exact errors. - **Deploy health-check trap (second occurrence)**: `deploy.sh` reported @@ -164,8 +199,8 @@ timestamp: 2026-09-14 + the two ownership regimes; [[Deployment Flow]] service-manager table corrected (dankserver media is no longer "bare containers, inventory only"). -## 2026-08-30 (night II) — frank-default-sightsound deployed; NPU SVA/IOMMU root cause -- **Deployed** `frank-default-sightsound` on Dankclaw: FLM v1.0.1 (`/usr/bin/flm`, +## 2026-08-30 (night II) — frank-npu deployed; NPU SVA/IOMMU root cause +- **Deployed** `frank-npu` on Dankclaw: FLM v1.0.1 (`/usr/bin/flm`, dpkg `fastflowlm`) serving the whole local registry (36 tags) on port 52626; primary model Gemma4 E4B IT NPU2 (vision + audio towers). First deploy crash-looped every 10 s: `Open /dev/accel/accel0 failed (err=-19)`. @@ -177,7 +212,7 @@ timestamp: 2026-09-14 kernel line — a consequence, not a GPU fault. - **Fix**: `iommu=pt` in `GRUB_CMDLINE_LINUX_DEFAULT` + reboot (passthrough keeps the iGPU default domain identity-mapped — zero DMA-translation overhead for - frank-default-large — while enabling IOMMU hardware + PASID, which SVA needs; + frank-large — while enabling IOMMU hardware + PASID, which SVA needs; PASID domains are paged regardless of the default-domain type). Post-boot: 30 IOMMU groups, zero SVA-bind errors since boot, unit `enabled`, `NRestarts=0` since boot. @@ -187,18 +222,18 @@ timestamp: 2026-09-14 279 prompt tokens consumed); audio tower proven with a control pair (440 Hz tone via `input_audio` = 37 prompt tokens vs 15 for the identical text-only control). Health probe is `/v1/version` — FLM has no `/health` route. -- `/scripts/frank-default-sightsound.env`, `/scripts/serve-frank-default-sightsound.sh`, - `/scripts/frank-default-sightsound.service` + deployer allowlist entries +- `/scripts/frank-npu.env`, `/scripts/serve-frank-npu.sh`, + `/scripts/frank-npu.service` + deployer allowlist entries (`c3ed3a6`, `cf0c541`) — service files and deploy wiring; unit is boot-persistent (`WantedBy=multi-user.target`, enabled, `Restart=on-failure`, `RestartSec=10`, `LimitMEMLOCK=infinity` — FLM requires unlimited memlock). -- **Docs**: new runbook [[frank-default-sightsound]] (linked from both indexes), +- **Docs**: new runbook [[frank-npu]] (linked from both indexes), AGENTS.md fleet table + runtime section updated with the IOMMU/SVA hard requirement. Client wiring: pi `models.json` registers the endpoint under the Dankclaw provider with the exact FLM registry tag as model id. ## 2026-08-30 (night) — frank fleet double swap: STRIX on its pinned fork, Huihui on FreeToken -- **Dankclaw / frank-default-large**: swapped to +- **Dankclaw / frank-large**: swapped to `kingjones777/Qwen3.8-Flash-Next-ROCmFP4-STRIX-GGUF` on the card's pinned `kingjones30/ROCmFPX` runtime (built at `/home/dank/GitPackages/kingjones-ROCmFPX/build`, `LLAMA_BUILD_WEBUI=OFF` @@ -212,7 +247,7 @@ timestamp: 2026-09-14 git flow; manual-process race during validation caught and fixed (unit was crash-looping on a bound port while its health check passed — check MainPID, not just /health). -- **Dankserver / frank-default-small**: swapped the model within +- **Dankserver / frank-small**: swapped the model within FreeToken v0.1.2 to `batsclamp/Huihui-Qwen3.6-35B-A3B-abliterated-FP8` (native block-fp8, same loader path and pool plan; 35 GB downloaded via `hf`, official checkpoint retained for rollback). Learned: @@ -220,7 +255,7 @@ timestamp: 2026-09-14 tok/s verified post-deploy. Both `.service` Descriptions refreshed. - Docs: [[kingjones-strix-rocmfp4]] reactivated as the large runbook (runtime build + swap procedure + validation), [[agentionai-fast-imatrix]] - marked RETIRED (rollback record), [[freetoken-frank-default-small]] + marked RETIRED (rollback record), [[freetoken-frank-small]] model sections updated, LLM index + AGENTS fleet tables refreshed. ## 2026-08-30 (late) — download chain proven end to end; qB credentials persisted diff --git a/shared/homepage/services.json b/shared/homepage/services.json index bd8f677..494634a 100644 --- a/shared/homepage/services.json +++ b/shared/homepage/services.json @@ -18,8 +18,8 @@ {"name":"Caddy","category":"admin","description":"The reverse proxy.","url":"","docs":"","probe":"127.0.0.1:80","method":"http","wip":false,"showLink":false}, {"name":"dnsmasq","category":"admin","description":"LAN name resolution.","url":"","docs":"","probe":"127.0.0.1:53","method":"tcp","wip":false,"showLink":false}, {"name":"Gluetun","category":"admin","description":"The outbound VPN tunnel.","url":"","docs":"","probe":"127.0.0.1:51820","method":"tcp","wip":true,"showLink":false}, - {"name":"frank-default-large","category":"admin","description":"The large LLM (27B) on Dankclaw.","url":"","docs":"","probe":"127.0.0.1:7770","method":"http","wip":false,"showLink":false}, - {"name":"frank-default-small","category":"admin","description":"The small LLM (35B MoE) on Dankserver.","url":"","docs":"","probe":"192.168.0.235:7770","method":"http","wip":false,"showLink":false}, + {"name":"frank-large","category":"admin","description":"The large LLM (27B) on Dankclaw.","url":"","docs":"","probe":"127.0.0.1:7770","method":"http","wip":false,"showLink":false}, + {"name":"frank-small","category":"admin","description":"The small LLM (35B MoE) on Dankserver.","url":"","docs":"","probe":"192.168.0.235:7770","method":"http","wip":false,"showLink":false}, {"name":"mariadb","category":"admin","description":"The media-stack database.","url":"","docs":"","probe":"192.168.0.235:3306","method":"tcp","wip":false,"showLink":false}, {"name":"valkey","category":"admin","description":"The SearXNG cache.","url":"","docs":"","probe":"127.0.0.1:6379","method":"tcp","wip":false,"showLink":false}, {"name":"Postgres","category":"admin","description":"The Gitea database.","url":"","docs":"","probe":"127.0.0.1:5432","method":"tcp","wip":false,"showLink":false},