searxng: wire paid Kagi engine with deploy-time key rendering

The stock SearXNG image ships a native kagi engine; enabling it needs an
API key that must never enter git, and SearXNG does not expand env vars
in settings.yml (the live secret_key literally was '${SEARXNG_SECRET}'
until now — the app tolerated the placeholder string silently).

- settings.yml: kagi engine enabled (weight 2, kg shortcut, paging off so
  exactly one API credit per aggregated query, timeout 8.0 vs 5.0 scrapers
  so a slow paid query is not a wasted credit); api_key stays ${KAGI_API_KEY}.
- new scripts/searxng-render-settings.py: deploy-time renderer, allowlisted
  to KAGI_API_KEY/SEARXNG_SECRET/SEARXNG_BASE_URL, fails the deploy loudly
  on an unresolvable placeholder, idempotent on redeploys.
- deploy-remote.sh copy_searxng_config runs the renderer against
  /opt/searxng/.env after copying settings.yml into /opt/searxng/config.
- KAGI_API_KEY placeholder added to dankclaw/.env.example (real key staged
  into the host-side /opt/searxng/.env, mode 600, out of band).
- bats: engine wiring, renderer substitution, loud-failure, deployer seam.
- docs: SearXNG.md Kagi section + renderer law; Providers.md carve-out on
  the no-credentials policy (paid engine acceptable when bounded + ordered).

Verified live on dankclaw: direct API probe via the gluetun netns (200,
data.search[] shape), then an aggregated query returned 29/29 results
tagged kagi, zero unresponsive engines.
This commit is contained in:
Frank
2026-09-26 23:25:55 -07:00
parent 4992e5a010
commit 7a8d992fce
7 changed files with 198 additions and 8 deletions
+15 -1
View File
@@ -1,5 +1,7 @@
# SearXNG settings — deployed to /opt/searxng/config/settings.yml on Dankclaw.
# Secret key and base URL come from environment variables (see .env.example).
# ${VAR} placeholders below are rendered at deploy time by
# scripts/searxng-render-settings.py from the host-side /opt/searxng/.env
# (SearXNG does not expand env vars in settings.yml itself).
use_default_settings: true
@@ -61,6 +63,18 @@ engines:
- name: duckduckgo videos
paging: false
timeout: 5.0
- name: kagi
engine: kagi
categories: [general, web]
shortcut: kg
api_key: "${KAGI_API_KEY}"
kagi_categ: search
disabled: false
weight: 2
# Paid API (billed per search): no pagination fan-out, and a wider
# timeout than the scrapers above so slow queries are not wasted credits.
paging: false
timeout: 8.0
- name: wikipedia
weight: 1
timeout: 5.0