SearXNG Self-Hosting Guide 2026: Docker + Open WebUI Search
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 SearXNG | Public SearXNG instance | Whoogle | |
|---|---|---|---|
| Best for | Private search + local AI web-search API | Zero-maintenance private search | Google-only proxy, minimal footprint |
| Cost | Your hardware (a Pi-class box is enough) | Free | Your hardware |
| The catch | You maintain it; your server IP does the querying | Operator sees your queries; JSON API usually disabled | Single 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:8080on 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: trueif the instance is reachable by anyone but you; setpublic_instance: trueonly if you genuinely intend to run a public instance. - Leave
jsonformat 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
- SearXNG repository — README and LICENSE (AGPL-3.0-or-later)
- Official container installation docs (compose instancing)
- searxng-docker deprecation notice
- SearXNG server settings — secret_key, limiter, public_instance
- Open WebUI SearXNG web-search provider docs
Recommended Gear
- 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?
Thanks for the feedback — it helps improve future articles.
Need hands-on help?
I offer 1-on-1 technical consulting for local AI setup, GPU selection, and AI coding tool configuration — same topics covered on this site.
Book a session — $49 / hour →