The ana-docker instance was returning zero results for every query while reporting healthy — 4.5 months stale (2026.4.17 against a current 2026.9.3), its engine scrapers rotted against sites that had changed. /healthz proves the web app answers and says nothing about whether search works, so seven days of green sat on top of a search box that found nothing. Moved to nh3-docker rather than updated in place, because the colo egress is the other half of the problem: 38.120.12.42 is a datacenter address that DuckDuckGo and Startpage CAPTCHA, while nh3-docker egresses residentially at 70.230.226.88. Same reasoning as the fleet's residential proxy for yt-dlp, applied at the source instead of around it. Config corrected along the way: base_url said searxng.pfi.local, a name retired on 2026-08-19, while the environment said something else — the env won so nothing broke and the file quietly lied. The karmasearch.videos removal key never matched, because the engine's real name has a space. scripts/searxng-health.sh asserts results > 0 across three unrelated queries. That is the check that would have caught this, and the only kind that can: the mechanism was healthy throughout. services/searxng-mcp exposes it as `web_search` at user scope, so every Claude Code session has it. Zero results raise rather than returning an empty list — an empty list is indistinguishable from a broken aggregator, which is precisely how this hid. Old instance stopped and removed; DNS alias repointed to searxng.nh3.internal.
80 lines
2.9 KiB
YAML
80 lines
2.9 KiB
YAML
# SearXNG — PFI fleet meta-search. Deployed on nh3-docker (10.100.50.40:9996).
|
|
#
|
|
# ⚠ WHY NH3 AND NOT THE COLO. Measured 2026-09-03:
|
|
# ana-docker egress 38.120.12.42 (datacenter) -> DuckDuckGo + Startpage CAPTCHA
|
|
# nh3-docker egress 70.230.226.88 (residential) -> no CAPTCHA
|
|
# Search engines gate datacenter ranges. Same reason the fleet keeps a
|
|
# residential SOCKS5 egress proxy on nh3-dev for yt-dlp. Running the search
|
|
# aggregator from a residential-egress site removes the problem at the source
|
|
# rather than proxying around it.
|
|
|
|
use_default_settings:
|
|
engines:
|
|
remove:
|
|
# Onion engines: no Tor proxy is configured here, so they only ever
|
|
# contribute timeouts.
|
|
- ahmia
|
|
- torch
|
|
# ⚠ Removal keys must match the engine's REAL name, spaces and all.
|
|
# `karmasearch.videos` (dotted) did NOT match on the old instance and the
|
|
# engine kept appearing in unresponsive_engines despite being "removed".
|
|
# The name is "karmasearch videos".
|
|
- karmasearch
|
|
- karmasearch videos
|
|
|
|
general:
|
|
instance_name: "SearXNG"
|
|
instance_about_url: false
|
|
contact_url: false
|
|
debug: false
|
|
# Public metrics page off — smaller attack surface on an unauthenticated
|
|
# internal service.
|
|
enable_metrics: false
|
|
|
|
search:
|
|
safe_search: 0
|
|
autocomplete: ""
|
|
default_lang: "auto"
|
|
# `json` is what makes this usable as a tool rather than only a web page.
|
|
# Removing it breaks every non-browser consumer, including Claude sessions.
|
|
formats:
|
|
- html
|
|
- json
|
|
# 3s is too tight for slower engines; 8s covers them without hanging the UI.
|
|
request_timeout: 8.0
|
|
# Ban an engine only briefly when it raises suspended-time. The default 86400
|
|
# means one bad afternoon silences an engine for a day.
|
|
ban_time_on_fail: 60
|
|
max_ban_time_on_fail: 600
|
|
|
|
server:
|
|
# secret_key comes from SEARXNG_SECRET in the environment — never hardcode it
|
|
# here. Generated + vaulted at nh3-docker/searxng-secret.
|
|
bind_address: "0.0.0.0"
|
|
port: 8080
|
|
# Enable ONLY with a limiter.toml AND a proxy that forwards X-Real-IP;
|
|
# otherwise it logs "X-Forwarded-For nor X-Real-IP header is set!" forever.
|
|
limiter: false
|
|
public_instance: false
|
|
# ⚠ Kept in sync with BASE_URL in compose.yaml. The old instance still said
|
|
# `https://searxng.pfi.local/` here — a name retired on 2026-08-19 — while the
|
|
# environment said something else. The env wins, so nothing broke, and the
|
|
# file quietly lied to everyone who read it.
|
|
base_url: "http://10.100.50.40:9996/"
|
|
method: "GET"
|
|
compression: true
|
|
image_proxy: false
|
|
|
|
# Outgoing pool — low-traffic private instance.
|
|
outgoing:
|
|
request_timeout: 6.0
|
|
max_request_timeout: 12.0
|
|
pool_connections: 100
|
|
pool_maxsize: 20
|
|
enable_http2: true
|
|
# No proxy needed: this host already egresses residentially (see header).
|
|
# If that ever changes, the fleet's NH3 SOCKS5 proxy is the fallback:
|
|
# proxies:
|
|
# all://:
|
|
# - socks5h://10.100.10.50:1080
|