SearXNG Self-Hosting Guide 2026: Docker + Open WebUI Search

searxngselfhostedprivacyopenwebuidocker

TL;DR: SearXNG is the AGPL-3.0 metasearch engine that queries Google, Bing, Brave, and 300+ other services without letting any of them profile you — and it’s the standard web-search backend for a local AI stack. The old searxng-docker install every 2024–2025 tutorial links to is now officially deprecated; the new compose flow lives in the main repo and takes about ten minutes. Self-host it if you run Open WebUI or Perplexica anyway; skip it if you just want one private search and can point at a public instance.

Self-hosted SearXNGPublic SearXNG instanceWhoogle
Best forPrivate search + local AI web-search APIZero-maintenance private searchGoogle-only proxy, minimal footprint
CostYour hardware (a Pi-class box is enough)FreeYour hardware
The catchYou maintain it; your server IP does the queryingOperator sees your queries; JSON API usually disabledSingle engine, project activity has slowed

Honest take: if a local LLM anywhere in your stack needs web search, self-hosted SearXNG is the default answer in 2026 — nothing else FOSS gives you a JSON search API across hundreds of engines on your own hardware.

What you’ll have running after this guide

  • A SearXNG instance at http://localhost:8080 on the current official two-container stack (SearXNG core + Valkey 9)
  • The JSON API enabled, wired into Open WebUI as its web-search provider — with the 403 error most people hit already fixed
  • A hardened config: secret key set, limiter on, and the instance kept off the public internet

First, the trap: the install guide you found is probably deprecated

Almost every SearXNG tutorial written before mid-2026 starts with git clone https://github.com/searxng/searxng-docker. That repo’s README now opens with a warning that it is superseded: new installations are supposed to use the compose templates shipped inside the main searxng/searxng repo, and existing searxng-docker deployments get a migration path in the official docs. The old stack also used Redis; the current one uses Valkey 9. If you follow a stale guide, you’ll be maintaining a deprecated layout from day one.

SearXNG itself (github.com/searxng/searxng, ~36.3k stars as of September 2026) has no versioned GitHub releases at all. It ships rolling, date-tagged container images — the .env.example cites tags like 2026.3.25-541c6c3cb — so “install the latest” genuinely means pulling a fresh image, not waiting for a release.

License check: AGPL-3.0, and what that actually means for you

SearXNG is AGPL-3.0-or-later — it’s the SPDX header on the README and the LICENSE file in the repo. For a home-lab self-hoster this changes nothing: run it, modify it, wire it into anything, no disclosure required. The AGPL network clause only bites if you modify SearXNG and serve it to other people — then you must offer them your modified source. Running the unmodified image publicly is also fine. This is the same license situation as Karakeep and Gadgetbridge: strong copyleft, zero practical restriction on personal self-hosting.

Install: the current official Docker Compose flow

Verified against the master-branch installation docs, September 2026. You need Docker (or Podman) and a user in the docker group.

# 1. Create the environment and config directories
mkdir -p ./searxng/core-config/
cd ./searxng/

# 2. Fetch the official compose template and env file
curl -fsSL \
  -O https://raw.githubusercontent.com/searxng/searxng/master/container/docker-compose.yml \
  -O https://raw.githubusercontent.com/searxng/searxng/master/container/.env.example

# 3. Create your .env
cp -i .env.example .env

# 4. Start it
docker compose up -d

Expected state after step 4:

$ docker compose ps
NAME            IMAGE  ...  STATUS        PORTS
searxng-core    ...         Up 3 minutes  0.0.0.0:8080->8080/tcp
searxng-valkey  ...         Up 3 minutes  6379/tcp

Two containers: searxng-core (the app, port 8080) and searxng-valkey (Valkey 9-alpine, used by the rate limiter and caching). Open http://localhost:8080 and you should get the search page immediately.

The .env file has exactly three knobs: SEARXNG_VERSION (pin a date tag instead of latest if you want reproducibility), SEARXNG_HOST, and SEARXNG_PORT. Everything else lives in core-config/settings.yml, which SearXNG reads from the mounted /etc/searxng/ directory.

One practical note: DockerHub rate-limits unauthenticated pulls now. If docker compose pull starts failing, switch the image to the GHCR mirror (ghcr.io/searxng/searxng).

The two settings you must change

Create or edit core-config/settings.yml:

use_default_settings: true

server:
  secret_key: "CHANGE-ME"   # openssl rand -hex 32
  limiter: true             # needs the Valkey container (you have it)

search:
  formats:
    - html
    - json                  # required for Open WebUI — see below

secret_key is used for cryptographic signing and ships as a placeholder — generate a real one with openssl rand -hex 32 (or set the SEARXNG_SECRET environment variable instead). limiter: true turns on bot/abuse rate limiting backed by Valkey. Restart with docker compose down && docker compose up -d after edits.

Wire it into Open WebUI (and fix the 403)

This is why the aifoss audience self-hosts SearXNG at all: it gives your local LLM a web-search tool that never touches a search API bill. In Open WebUI, set the web-search engine to searxng and the query URL to:

http://searxng-core:8080/search?q=<query>

Use the container name (or your host’s LAN IP) — localhost inside the Open WebUI container points at the container itself, the same Docker-network trap we covered in the n8n + Ollama guide.

The problem you will hit: Open WebUI’s searches come back 403 Client Error: Forbidden even though the SearXNG web page works fine in your browser. The cause is that SearXNG’s default formats: list contains only html — the JSON API is disabled out of the box, and Open WebUI queries it with &format=json. The fix is the json line in the settings snippet above. No SearXNG restart, no amount of Open WebUI fiddling fixes it otherwise; this one bites nearly everyone because the default changed silently versus what older tutorials assume.

The same JSON endpoint is what Perplexica uses for its Perplexity-style answer engine, and what an n8n HTTP node can call for search-driven automations. One SearXNG container serves all of them.

What 300+ engines actually means

The default settings.yml on master declares 345 engine entries — Google, Bing, Brave, DuckDuckGo, Wikipedia, arXiv, GitHub, Stack Overflow, and a long tail of specialized databases. Not all are enabled by default, and none require API keys for the standard web engines: SearXNG scrapes or uses public endpoints, which is why results occasionally break when an upstream engine changes markup (the weekly-ish image releases exist largely to ship those engine fixes — another reason not to pin an old tag forever).

Enable or disable engines per-category in settings.yml, or interactively in the web UI preferences. Bang syntax works like DuckDuckGo: !gh searxng searches GitHub directly.

Privacy: what it protects, and what it doesn’t

Be precise about the threat model, because “private search” oversells it:

  • Protected: no cookies, no tracking, no per-user profile at Google/Bing/etc. Upstream engines see queries arriving from your server’s IP, mixed across every engine and every user of your instance, with no browser fingerprint attached.
  • Not protected: your server’s IP still makes the queries. A single-user home instance means your home IP’s query stream is visible to upstream engines — aggregated, but yours. If that matters to your threat model, route SearXNG’s outbound traffic through a VPN, or accept the trade.
  • Not a cache: every search hits upstream engines live. There’s no stored index, which also means result quality is exactly as good as the engines you enable.

Hardening checklist

  • Don’t port-forward 8080 to the internet. If you need remote access, put it behind a reverse proxy with TLS or, better, reach it over WireGuard/Tailscale — the same posture we recommend in the Ollama security guide after 175K exposed Ollama instances made the point for us.
  • Keep limiter: true if the instance is reachable by anyone but you; set public_instance: true only if you genuinely intend to run a public instance.
  • Leave json format enabled only on trusted networks — it’s the machine-readable endpoint bots love.
  • Update monthly: docker compose pull && docker compose up -d, and re-fetch the compose template occasionally since the official layout does change (as the searxng-docker deprecation proved).

When NOT to self-host SearXNG

If you don’t run any local AI tooling and just want private search in a browser, a reputable public instance from searx.space gives you 90% of the benefit with zero maintenance — you’re trusting the operator instead of Google, but you’re also not the sole IP behind the queries. And if all you need is a Google proxy, Whoogle is lighter, though its single-engine scope and slower project activity make SearXNG the safer multi-year bet. Hardware is a non-issue either way: SearXNG is a Python app with no models to load, so a Raspberry Pi 5 runs it comfortably alongside the rest of a privacy stack — the GPU box with an RTX 3060 12GB for Open WebUI + Ollama can host it too, and heavier inference can rent from RunPod while search stays home. For the server-side hardware angle, see runaihome.com; for wiring search-augmented context into coding tools, aicoderscope.com covers that side.

FAQ

Does SearXNG need an API key for Google or Bing results? No. It queries the engines’ public endpoints directly — no keys, no billing. The flip side is occasional breakage when an engine changes its markup, fixed by pulling a newer image.

Why does Open WebUI get a 403 from my SearXNG instance? The JSON API is off by default. Add json under search.formats in core-config/settings.yml and restart the container. The default list contains only html.

Is it legal to run SearXNG for my whole household or team? Yes. AGPL-3.0 places no restriction on use; the source-disclosure obligation only triggers if you modify SearXNG and offer it to others as a service.

Sources

  • Raspberry Pi 5 — runs SearXNG (and most of a privacy stack) on a few watts
  • RTX 3060 12GB — the budget GPU for the Ollama + Open WebUI box SearXNG plugs into

Was this article helpful?