SearXNG: Self-Hosted Private Search Engine¶
SearXNG is a self-hosted meta-search engine — it queries multiple search engines on your behalf and returns aggregated results, without tying any of those queries to your identity. No search history, no profile building, no query leakage to Google or Bing. If you're running a homelab and care about privacy, this is one of the first things you should spin up. It also doubles as a web search backend for AI tools like Open WebUI, which is how I use it in my MajorTwin setup.
The Short Answer¶
docker run -d \
--name searxng \
--restart always \
-p 8080:8080 \
-v searxng-data:/etc/searxng \
searxng/searxng:latest
Then open http://localhost:8080 — search should work immediately with default settings.
Background¶
SearXNG is a fork of SearX with active maintenance, a cleaner UI, and better defaults. When you search, SearXNG sends your query to whatever engines you've configured (Google, Bing, DuckDuckGo, Brave, etc.), aggregates the results, deduplicates them, and returns them to you. The search engines see a request from your server's IP, not from your personal device or account.
The privacy benefit is real but worth understanding correctly: SearXNG hides you from the search engines. Your ISP can still see that your server is making search requests, and whoever hosts your SearXNG instance (in this case, you) can see all queries in the logs. For a personal homelab instance, that's a non-issue — you're the only user. The point is keeping Google and Bing from building a profile on your searches.
Steps¶
1. Deploy SearXNG with Docker¶
The quickest path is a single docker run. For anything you're keeping long-term, use a compose file so it's easier to manage.
docker run (quick test):
docker run -d \
--name searxng \
--restart always \
-p 8080:8080 \
-v searxng-data:/etc/searxng \
searxng/searxng:latest
docker-compose.yml (recommended):
services:
searxng:
image: searxng/searxng:latest
container_name: searxng
restart: always
ports:
- "8080:8080"
volumes:
- searxng-data:/etc/searxng
environment:
- SEARXNG_BASE_URL=http://localhost:8080/
volumes:
searxng-data:
2. Verify It's Running¶
Open http://localhost:8080 in a browser and run a test search. You should get results immediately.
3. Configure Settings¶
SearXNG stores its config in settings.yml inside the volume. Get to it:
# Find where Docker stored the volume
docker volume inspect searxng-data
# Or exec into the container to edit directly
docker exec -it searxng sh
vi /etc/searxng/settings.yml
Key settings worth knowing:
# Set your instance name
general:
instance_name: "MajorSearch"
# Control which engines are enabled
engines:
- name: google
engine: google
shortcut: g
disabled: false
- name: brave
engine: brave
shortcut: br
disabled: false
- name: duckduckgo
engine: duckduckgo
shortcut: ddg
disabled: false
# Disable search logging if you want zero local records
general:
debug: false
# Rate limiting — important if you expose this publicly
server:
limiter: true
public_instance: false
After editing settings.yml, restart the container:
4. Connect SearXNG to Open WebUI¶
This is the main reason I run SearXNG — as the web search backend for Open WebUI so the AI assistant can search the web without any query going to a third-party API.
In Open WebUI:
1. Go to Settings > Web Search
2. Enable Web Search
3. Set Search Engine to searxng
4. Set SearXNG URL to http://host.docker.internal:8080 (if Open WebUI is also in Docker) or http://localhost:8080 (if accessing from outside Docker)
Important: If Open WebUI is running in Docker and SearXNG is also in Docker, use host.docker.internal as the hostname, not localhost. Containers can't reach each other via localhost — that resolves to the container itself.
# Open WebUI running in Docker → SearXNG running in Docker
http://host.docker.internal:8080
# Open WebUI in browser → SearXNG in Docker (same machine)
http://localhost:8080
# Remote device via Tailscale
http://yourserver.tail-xxxxx.ts.net:8080
5. Access via Tailscale (Remote Use)¶
SearXNG binds to 0.0.0.0 by default in Docker, so it's already reachable over your Tailscale tailnet once Tailscale is running on the server. No extra config needed. Access it from any Tailscale device:
If you want to keep it local-only and not reachable over Tailscale, bind it to a specific interface in the compose file:
Gotchas & Notes¶
-
localhostvshost.docker.internaltrips everyone up. If Open WebUI can't reach SearXNG and both are in Docker, the URL needs to behttp://host.docker.internal:8080, nothttp://localhost:8080. On Linux,host.docker.internalmay not resolve automatically — you may need to add--add-host=host.docker.internal:host-gatewayto your Open WebUIdocker runcommand. -
Some search engines will rate-limit or block you if you send too many queries too fast. Google is the most aggressive about this. If you start getting CAPTCHAs or empty results from a specific engine, disable it in
settings.ymland rely on others. Brave and DuckDuckGo tend to be more tolerant for self-hosted instances. -
Don't expose this publicly without rate limiting. The
limiter: truesetting insettings.ymlis there for a reason. A public SearXNG instance with no rate limiting will get hammered and your IP will get blocked by upstream search engines fast. -
Results quality varies by engine selection. I run Google, Brave, and DuckDuckGo as my primary three. Google gives the best results but is the most aggressive about rate limiting. Brave is a solid fallback. Having three engines means you get deduplication and better coverage than any single engine alone.
-
Docker resource limits matter. SearXNG is lightweight, but if you're running it alongside other services (Ollama, Open WebUI, etc.), make sure Docker Desktop on Windows has enough memory allocated. 8GB minimum for the full stack — set this in Docker Desktop > Settings > Resources > Memory.
-
The UI has a settings page at
http://localhost:8080/preferenceswhere you can configure engines, themes, and language without touching the config file. Changes made here are per-session unless you're logged in, but it's useful for testing.
See Also¶
- [[tailscale-remote-access]]
- [[open-webui-setup]]
- [[docker-compose-patterns]]
- [[privacy-tools-overview]]