[email protected]

How-to · Local AI for Business

Self-hosting SearXNG: Docker, hardening and Open WebUI

Editorial note: Versions, commands and prices may change. Please verify critical steps independently before production use. This guide does not replace individual professional, legal or tax advice.

Have SearXNG operated for you, or set up web search for AI chats? WZ-IT sets up and runs SearXNG as a private metasearch: engines, access protection, updates and monitoring. Independently of that, the AI platform with Open WebUI (from €149.90 excl. VAT per month) includes web search in the chat. View SearXNG hosting & operations

SearXNG is a free metasearch engine: it accepts a search query, forwards it to configured search engines and merges the results. Companies use it to give employees or AI chats web search without the queries ending up under a user profile at a provider. This guide covers installation, configuration, hardening and the connection to Open WebUI. The configuration steps were reproduced on 28 October 2026 with the current container image; the test conditions are listed under “Status and method”. As of October 2026.

Table of contents

What SearXNG is and what it is not

SearXNG merges the results of other search engines and does not store information about its users (project documentation). It does not run a web index of its own. Two properties follow that shape operations: result quality is the sum of what the enabled engines deliver, and every query is passed on to those engines.

For the strongest search results Open WebUI recommends hosted search APIs. SearXNG remains useful when a self-hosted, privacy-friendly metasearch engine is wanted, with result quality depending heavily on the upstream engines, rate limits and instance configuration (Open WebUI documentation).

AGPL-3.0 licence: consequences for use and changes

SearXNG is licensed under the GNU Affero General Public License version 3 (LICENSE in the repository). For use in a company this means:

Action Consequence under the LICENSE
Run the unmodified program, including commercially Section 2 affirms “unlimited permission to run the unmodified Program”
Adjust configuration (settings.yml, limiter.toml, environment variables) This is configuration, the program code stays unchanged; section 13 applies to modification of the program
Modify the program code and make it available to users over a network Section 13: the modified version must offer all users interacting with it over the network the source of that version
Pass on copies or images Sections 4 to 6: include the licence text and notices; if the program is passed on without its source, section 6 applies (provide or offer the source); for modifications the conditions of section 5 are added

Open WebUI and other clients talk to SearXNG over HTTP. Whether licence obligations extend to adjacent software is a legal question for the individual case. This section is not legal advice; anyone who modifies code or passes on images should have the position reviewed beforehand.

Installation with Docker Compose

The project documentation recommends Compose as the standard route (Installation container):

mkdir -p ./searxng/core-config/ && cd ./searxng/
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
cp .env.example .env

In the .env, restrict where the port is published (reasons in the hardening section), then start:

printf 'SEARXNG_HOST=127.0.0.1\nSEARXNG_PORT=8080\n' >> .env
docker compose up -d

The template starts two services: core (SearXNG) and valkey (database for the limiter). Two storage locations must be kept: the directory core-config (bind mount to /etc/searxng, configuration) and the volume core-data (mapped to /var/cache/searxng). On first start the container creates settings.yml from a template. It contains use_default_settings: true, a randomly generated secret_key and image_proxy: true. The default value ultrasecretkey makes the startup abort.

settings.yml: the settings that matter

With use_default_settings: true it is enough to enter deviations from the defaults. Example for an instance acting as a search backend for AI:

use_default_settings:
  engines:
    keep_only:
      - brave
      - duckduckgo
      - wikipedia

server:
  secret_key: "…"      # generated by the container, do not change
  image_proxy: true

search:
  default_lang: "de"
  formats:
    - html
    - json

general:
  open_metrics: "long-random-password"
Setting Effect
search.formats Enables JSON for API use. The default is html only, a format that is not enabled returns HTTP 403 (Search API)
engines.keep_only or remove Selects the engines; a disabled engine is switched on by an entry - name: bing with disabled: false under engines: (settings.yml). By default roughly 80 of 352 engines are active, including DuckDuckGo, Brave and Wikipedia; the general web engines of Google and Bing are disabled (settings.yml of 28 October 2026). The list changes with the version
server.limiter, valkey.url Bot protection, requires Valkey. As environment variables SEARXNG_LIMITER and SEARXNG_VALKEY_URL
search.suspended_times How long an engine is suspended after errors, default 3,600 s after a CAPTCHA, 180 s after Access Denied and Too Many Requests; special cases: Cloudflare CAPTCHA 15 days, reCAPTCHA 7 days
outgoing.request_timeout, outgoing.proxies Timeout of queries to the engines (default 3 s) and optional proxies for outgoing requests (outgoing)
general.open_metrics Password for the metrics endpoint /metrics (general)

Hardening: port, access and limiter

Port. Without SEARXNG_HOST the template publishes the port on all addresses. Published Docker ports are reachable from outside as well (Docker: Port publishing) and bypass ufw rules (Docker: Packet filtering). With 127.0.0.1 the port is reachable only on the host from Docker Engine 28.0.0 onwards; in older versions hosts in the same L2 segment can also reach ports published to localhost. Open WebUI in the same Compose network needs no published port: the service name core resolves in the network, so the URL is http://core:8080/search.

Access. For users outside the host, put a reverse proxy or VPN with authentication in front; the header configuration for NGINX and Apache is in the project documentation. The limiter restricts request rates and is not a login.

Limiter. It protects the engines from load by blocking bots at the instance (Limiter). Which mode fits depends on who accesses it:

Operation Limiter Protection
Only Open WebUI and defined services on the internal network off (default) network boundary, no published port
Access for people or additional clients on, with Valkey rate limit and header checks, exempt services via pass_ip

The limiter counts requests with format other than html separately and allows only 4 per hour per IP (per /48 network for IPv6) (API_MAX and API_WINDOW in the bot detection). In the test, the fifth JSON request from the Compose network received HTTP 429. The limiter also blocks clients without suitable Accept, Accept-Encoding and Accept-Language headers as well as known libraries such as python-requests. Anyone enabling it for API clients exempts their network. docker network inspect searxng_default shows the subnet:

# core-config/limiter.toml
[botdetection.ip_lists]
pass_ip = [
  '172.22.0.0/16',   # subnet of the Compose network that contains Open WebUI
]

In the .env, SEARXNG_LIMITER=true and SEARXNG_VALKEY_URL=valkey://valkey:6379/0 enable the limiter. Behind a reverse proxy, X-Forwarded-For or X-Real-IP and trusted_proxies must be set correctly, otherwise the limiter only sees the proxy's IP.

Connecting web search in Open WebUI

Open WebUI supports SearXNG as a search provider. The URL points to the /search endpoint; Open WebUI adds the parameters q, format=json, language and others itself (SearXNG guide, community-contributed).

services:
  open-webui:
    environment:
      ENABLE_WEB_SEARCH: "True"
      WEB_SEARCH_ENGINE: "searxng"
      SEARXNG_QUERY_URL: "http://core:8080/search"
      WEB_SEARCH_RESULT_COUNT: "3"
      WEB_SEARCH_CONCURRENT_REQUESTS: "2"   # example value
Variable Meaning (default)
SEARXNG_QUERY_URL Address of the /search endpoint
SEARXNG_LANGUAGE Search language passed to SearXNG (all), overrides search.default_lang of the instance
WEB_SEARCH_RESULT_COUNT Number of results used (3)
WEB_SEARCH_CONCURRENT_REQUESTS Concurrent search requests, 0 means unlimited (0)
BYPASS_WEB_SEARCH_WEB_LOADER Use snippets only, do not load result pages (off)
ENABLE_WEB_SEARCH_CONFIRMATION Users confirm every search (off)
WEB_SEARCH_DOMAIN_FILTER_LIST Allowed or blocked domains in the results

These variables apply on first start only. Afterwards the values live in the database and are changed in the admin settings under Web Search, unless ENABLE_PERSISTENT_CONFIG is set to False (environment variables, Open WebUI v0.12.1). A test from outside: curl 'http://127.0.0.1:8080/search?q=test&format=json'. HTTP 403 means json is missing from search.formats. HTTP 429 means the limiter is blocking the client.

Limits: blocked engines and varying quality

SearXNG passes queries on to search engines that do not welcome automated requests. Consequences for operations:

  • Engines drop out, search does not. If an engine answers with a CAPTCHA, 403 or 429, it is usually suspended for the block period. The instance keeps returning hits from the remaining engines. In the test on 28 October 2026, DuckDuckGo returned a CAPTCHA on the very first request from an office connection in Germany. The duckduckgo engine sets no suspension time on a CAPTCHA and is queried again on every request. The results came from the other engines, and the user saw no error.
  • Quality varies. When a source is missing, order and hits change. For agents that must cite sources this is a measurable risk.
  • Agents create load. Several searches per answer can look like automated load to an engine. WEB_SEARCH_CONCURRENT_REQUESTS, a deliberate engine selection and, where needed, proxies limit this.
  • Search results are not trustworthy. Loaded web pages can contain instructions for the model, see Protection against prompt injection.

SearXNG and privacy: what goes to search engines

A private instance removes the link to the user, but not the search query. The project documentation describes what SearXNG removes (Why use a private instance?):

Item Goes to the search engine?
Search term with language and page number Yes, to the enabled engines of the selected category. Open WebUI passes no category, so general applies
IP address of the user No. The engine sees the IP of the instance or of a configured proxy
Cookies No, the browser profile is generated randomly for each request
Chat history and documents Not part of the request. Which terms the model formulates depends on the question and the model
Result pages Not via SearXNG: Open WebUI loads them itself, using the IP of the Open WebUI server unless a proxy is set
Logs of the instance With the operator, the scope is in their hands

Legal basis, contracts and input rules are to be assessed separately, see GDPR-compliant AI: assessment criteria.

Updates and monitoring

Updates. Images carry date and commit as the tag, for example 2026.10.28-c360868e5. SEARXNG_VERSION in the .env pins a version. Update with docker compose down, docker compose pull and docker compose up -d. For larger changes, reload and compare the templates (docker-compose.yml, .env.example). Engines change with the image: check engine errors after every update.

Endpoint Purpose
/healthz Reachability, answers OK and is exempt from the limiter
unresponsive_engines in the JSON Per request, the engines that failed with the reason
/stats/errors Errors per engine as JSON, in the test CAPTCHA at DuckDuckGo with 100 %
/metrics OpenMetrics with reliability, response time and result count per engine, basic auth with open_metrics

Alert on the number of reachable engines and the reliability per engine. The container can be running while only one engine still answers. When several engines fail, operations need a fallback, for example switching to a search API.

When self-hosting pays off

Situation Better fit
Search terms should not end up with an additional API provider own SearXNG instance
Guaranteed quality and availability of results hosted search API, SearXNG as fallback
Few users, occasional search hosted search API, if running an own instance is out of proportion
Many automated searches by agents SearXNG with engine selection, proxies and a fallback

Status and method

  • Status: 28 October 2026. Documentation and source of SearXNG (build 2026.10.28-c360868e5) and Open WebUI (documentation for v0.12.1) were retrieved on 28 October 2026.
  • Test setup: Compose template from the repository with Valkey 9, Docker Desktop. Checked: first start with generated settings.yml, JSON request before and after search.formats (403 and 200), limiter with Valkey (fifth JSON request HTTP 429, no block with pass_ip), access from a container via the service name core with the headers Open WebUI sends, keep_only, /healthz, /stats/errors and /metrics.
  • Limits of the test: one network, one day. Which engines block depends on IP, load and time and is not transferable.
  • Sources: the linked pages of SearXNG, Open WebUI, Docker and the LICENSE in the repository.

Tables and figures may be reused with attribution and a link to this article.

Our approach at WZ-IT

On the page SearXNG hosting & operations WZ-IT describes operating it as a private metasearch: engines, limiter, proxy, Valkey, logging and access are configured to fit the use, data flows and enabled engines are documented, and public instances additionally get rate limits and abuse protection. Updates, monitoring and backup are part of operations.

The AI platform is a dedicated Open WebUI instance with models operated in Germany by German providers and includes web search in the chat, so no search service of your own has to be run for it. Only the search terms go to search engines, and administrators disable web search per group. The Start package for up to 10 users costs from €149.90 excl. VAT per month (as of October 2026). On request we integrate SearXNG as the search service into the platform, as well as Docling for document processing.

Further guides

Set up web search for your own AI? We run SearXNG as a service or provide web search with the AI platform. SearXNG hosting & operations · AI platform

Further reading: Web search in Open WebUI: providers compared

Rather have it operated?

You'd rather not run Local AI for Business yourself? WZ-IT handles setup, operations and maintenance - privacy-focused from Germany.

Enquiry

Assess local AI for your use case

Start with the AI Cube or have us assess a custom AI platform, knowledge connection, or integration.

  • Straight with Timo and Robin - no sales team, no pitch
  • A professional assessment of your situation
  • Concrete next steps for infrastructure, software or AI

The conversation is free and non-binding.

I got to know Timo and Robin as dedicated and professional partners who make a lot of things possible for their clients that initially seem impossible. I felt very well advised. The services offered have thoroughly convinced me. (translated)
Andrea PawlowskiCommunications Manager, Golem.de, Germany
Timo and Robin, founders of WZ-IT

Assess local AI for your use case

I got to know Timo and Robin as dedicated and professional partners who make a lot of things possible for their clients that initially seem impossible. I felt very well advised. The services offered have thoroughly convinced me. (translated)
Andrea PawlowskiCommunications Manager, Golem.de, Germany

Frequently Asked Questions

Answers to the most important questions

Knowledge

More on Local AI for Business

All Local AI for Business articles

Companies worldwide trust WZ-IT

  • Stadtwerke Brühl
  • DGHO e.V.
  • solarwerkstatt berlin
  • Krüger Dirndl
  • ABCO Water Systems
  • Golem.de
  • EVADXB
  • nextGYM
  • AInergy
  • ml&s
  • Odiseo Solutions
  • Annota
  • ARGE
  • SweetConnect GmbH
  • Aphy AG
  • CORGOS
  • Rekorder
  • SolidProof
  • Yonju
  • Keymate
  • Paritel
  • Mr. Clipart
  • Millenium
  • Negosh
  • Führerscheinmacher
  • BTI
  • Deutsche Gesellschaft für Datenschutz
Read client reviews