add SearXNG safe-search script and improve OWUI search env vars
- New configure-searxng-safesearch.sh: set strict/moderate/none level, disable engines that can't enforce the chosen level (torrent sites, mojeek, baidu, yandex, nvidious/piped/peertube video frontends), updates &safesearch= in SEARXNG_QUERY_URL, and restarts searxng - Add RAG_WEB_SEARCH_RESULT_COUNT=5 and RAG_WEB_SEARCH_CONCURRENT_REQUESTS=10 to Open WebUI env in both setup scripts - Add &safesearch=0 to SEARXNG_QUERY_URL so the script can find/replace it - Sync ENABLE_TOOL_SERVERS=true into laptop_full_setup.sh (was missing) https://claude.ai/code/session_012gDnantBmFTWZGCiKyjazx
This commit is contained in:
Executable
+136
@@ -0,0 +1,136 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# configure-searxng-safesearch.sh
|
||||||
|
# Set SearXNG safe-search level and disable engines that can't enforce it.
|
||||||
|
#
|
||||||
|
# Usage:
|
||||||
|
# ./configure-searxng-safesearch.sh strict # block explicit content
|
||||||
|
# ./configure-searxng-safesearch.sh moderate # filter but not strict
|
||||||
|
# ./configure-searxng-safesearch.sh none # unfiltered (default)
|
||||||
|
#
|
||||||
|
# What it does:
|
||||||
|
# 1. Updates ~/docker/ai-stack/searxng/settings.yml
|
||||||
|
# 2. Disables engines that don't honour the chosen safe-search level
|
||||||
|
# 3. Updates SEARXNG_QUERY_URL in docker-compose.yml to pass &safesearch=N
|
||||||
|
# 4. Restarts the SearXNG container to apply changes
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
# ── Helpers ───────────────────────────────────────────────────────────────────
|
||||||
|
red() { printf '\e[31m%s\e[0m\n' "$*"; }
|
||||||
|
grn() { printf '\e[32m%s\e[0m\n' "$*"; }
|
||||||
|
blu() { printf '\e[34m%s\e[0m\n' "$*"; }
|
||||||
|
die() { red "ERROR: $*"; exit 1; }
|
||||||
|
ok() { grn " ✓ $*"; }
|
||||||
|
info() { blu " → $*"; }
|
||||||
|
|
||||||
|
LEVEL="${1:-moderate}"
|
||||||
|
BASE="${BASE:-$HOME/docker/ai-stack}"
|
||||||
|
SETTINGS="$BASE/searxng/settings.yml"
|
||||||
|
COMPOSE="$BASE/docker-compose.yml"
|
||||||
|
|
||||||
|
# ── Validate ──────────────────────────────────────────────────────────────────
|
||||||
|
case "$LEVEL" in
|
||||||
|
strict|moderate|none) ;;
|
||||||
|
*) die "Unknown level '$LEVEL'. Use: strict, moderate, or none" ;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
[[ -f "$SETTINGS" ]] || die "SearXNG settings not found: $SETTINGS"
|
||||||
|
|
||||||
|
# ── Map level → SearXNG integer ───────────────────────────────────────────────
|
||||||
|
case "$LEVEL" in
|
||||||
|
none) SAFE_INT=0 ;;
|
||||||
|
moderate) SAFE_INT=1 ;;
|
||||||
|
strict) SAFE_INT=2 ;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
info "Setting safe_search = $LEVEL (${SAFE_INT})"
|
||||||
|
|
||||||
|
# ── Engines that cannot enforce safe-search ───────────────────────────────────
|
||||||
|
# These are disabled for moderate/strict because they either have no
|
||||||
|
# safe-search API parameter, or don't reliably honour it.
|
||||||
|
#
|
||||||
|
# Torrent/P2P — inherently unfiltered
|
||||||
|
TORRENT_ENGINES=(
|
||||||
|
"1337x"
|
||||||
|
"piratebay"
|
||||||
|
"nyaa"
|
||||||
|
"torrentz"
|
||||||
|
"kickass torrents"
|
||||||
|
)
|
||||||
|
|
||||||
|
# General web / image / video engines without safe-search support
|
||||||
|
NO_SAFESEARCH_ENGINES=(
|
||||||
|
"mojeek" # no safe-search parameter
|
||||||
|
"naver" # Korean engine, no safe-search API
|
||||||
|
"baidu" # Chinese engine, no safe-search for non-CN queries
|
||||||
|
"yandex" # nominally supports it but does not reliably enforce
|
||||||
|
"invidious" # YouTube frontend, no filtering
|
||||||
|
"piped" # YouTube frontend, no filtering
|
||||||
|
"peertube" # federated video, no filtering
|
||||||
|
"sepiasearch" # PeerTube index, no filtering
|
||||||
|
)
|
||||||
|
|
||||||
|
ALL_SKIP=("${TORRENT_ENGINES[@]}" "${NO_SAFESEARCH_ENGINES[@]}")
|
||||||
|
|
||||||
|
# ── Extract existing secret key (avoid regenerating on every run) ─────────────
|
||||||
|
SECRET_KEY=$(grep -oP '(?<=secret_key: ")[^"]+' "$SETTINGS" 2>/dev/null || true)
|
||||||
|
[[ -z "$SECRET_KEY" ]] && SECRET_KEY=$(openssl rand -hex 32)
|
||||||
|
|
||||||
|
# ── Build engine-override block ───────────────────────────────────────────────
|
||||||
|
build_overrides() {
|
||||||
|
local disabled="$1" # true or false
|
||||||
|
for engine in "${ALL_SKIP[@]}"; do
|
||||||
|
printf ' - name: %s\n disabled: %s\n' "$engine" "$disabled"
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
if [[ "$LEVEL" == "none" ]]; then
|
||||||
|
OVERRIDE_BLOCK=$(build_overrides false)
|
||||||
|
else
|
||||||
|
OVERRIDE_BLOCK=$(build_overrides true)
|
||||||
|
fi
|
||||||
|
|
||||||
|
# ── Write settings.yml ────────────────────────────────────────────────────────
|
||||||
|
cat > "$SETTINGS" << YAML
|
||||||
|
use_default_settings: true
|
||||||
|
general:
|
||||||
|
instance_name: "Local Search"
|
||||||
|
server:
|
||||||
|
secret_key: "$SECRET_KEY"
|
||||||
|
limiter: false
|
||||||
|
search:
|
||||||
|
safe_search: $SAFE_INT
|
||||||
|
default_lang: "en"
|
||||||
|
formats: [html, json]
|
||||||
|
engines:
|
||||||
|
$OVERRIDE_BLOCK
|
||||||
|
YAML
|
||||||
|
|
||||||
|
ok "Updated settings.yml (safe_search: $SAFE_INT)"
|
||||||
|
|
||||||
|
# ── Update &safesearch= in SEARXNG_QUERY_URL inside docker-compose.yml ────────
|
||||||
|
if [[ -f "$COMPOSE" ]]; then
|
||||||
|
# Strip any existing &safesearch=N, then append the current value
|
||||||
|
sed -i -E \
|
||||||
|
"s|(SEARXNG_QUERY_URL=http://searxng:[0-9]+/search\?[^&\n]*)(&safesearch=[0-9])?|\1\&safesearch=${SAFE_INT}|g" \
|
||||||
|
"$COMPOSE"
|
||||||
|
ok "Updated SEARXNG_QUERY_URL in docker-compose.yml (&safesearch=${SAFE_INT})"
|
||||||
|
else
|
||||||
|
info "docker-compose.yml not found — skipping URL update"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# ── Restart SearXNG ───────────────────────────────────────────────────────────
|
||||||
|
if docker ps --format '{{.Names}}' 2>/dev/null | grep -q '^searxng$'; then
|
||||||
|
info "Restarting SearXNG..."
|
||||||
|
docker restart searxng
|
||||||
|
ok "SearXNG restarted"
|
||||||
|
else
|
||||||
|
info "SearXNG is not running — changes take effect on next start"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo
|
||||||
|
grn "Safe-search level: $LEVEL"
|
||||||
|
if [[ "$LEVEL" != "none" ]]; then
|
||||||
|
info "Disabled ${#ALL_SKIP[@]} engines that can't enforce '${LEVEL}'"
|
||||||
|
for e in "${ALL_SKIP[@]}"; do printf ' - %s\n' "$e"; done
|
||||||
|
fi
|
||||||
@@ -780,7 +780,10 @@ ${OLLAMA_VOLUME_LINE}
|
|||||||
- ENABLE_OPENAI_API=true
|
- ENABLE_OPENAI_API=true
|
||||||
- ENABLE_RAG_WEB_SEARCH=true
|
- ENABLE_RAG_WEB_SEARCH=true
|
||||||
- RAG_WEB_SEARCH_ENGINE=searxng
|
- RAG_WEB_SEARCH_ENGINE=searxng
|
||||||
- SEARXNG_QUERY_URL=http://searxng:8080/search?q=<query>&format=json
|
- SEARXNG_QUERY_URL=http://searxng:8080/search?q=<query>&format=json&safesearch=0
|
||||||
|
- RAG_WEB_SEARCH_RESULT_COUNT=5
|
||||||
|
- RAG_WEB_SEARCH_CONCURRENT_REQUESTS=10
|
||||||
|
- ENABLE_TOOL_SERVERS=true
|
||||||
- WEBUI_AUTH=true
|
- WEBUI_AUTH=true
|
||||||
- WEBUI_URL=${WEBUI_URL:-}
|
- WEBUI_URL=${WEBUI_URL:-}
|
||||||
depends_on:
|
depends_on:
|
||||||
|
|||||||
+4
-2
@@ -553,9 +553,11 @@ services:
|
|||||||
- ENABLE_OPENAI_API=true
|
- ENABLE_OPENAI_API=true
|
||||||
- ENABLE_RAG_WEB_SEARCH=true
|
- ENABLE_RAG_WEB_SEARCH=true
|
||||||
- RAG_WEB_SEARCH_ENGINE=searxng
|
- RAG_WEB_SEARCH_ENGINE=searxng
|
||||||
- SEARXNG_QUERY_URL=http://searxng:8080/search?q=<query>&format=json
|
- SEARXNG_QUERY_URL=http://searxng:8080/search?q=<query>&format=json&safesearch=0
|
||||||
- WEBUI_AUTH=true
|
- RAG_WEB_SEARCH_RESULT_COUNT=5
|
||||||
|
- RAG_WEB_SEARCH_CONCURRENT_REQUESTS=10
|
||||||
- ENABLE_TOOL_SERVERS=true
|
- ENABLE_TOOL_SERVERS=true
|
||||||
|
- WEBUI_AUTH=true
|
||||||
depends_on:
|
depends_on:
|
||||||
ollama: {condition: service_healthy}
|
ollama: {condition: service_healthy}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user