Most of us type queries into someone else’s machine and trust that the logs stay private, the ranking stays neutral, and the profile they build about us stays unused. That trust is the product. If you would rather own the search box than rent it, SearXNG is the cleanest way to run a real meta-search engine on hardware you control — it queries dozens of upstream engines, strips your identity before it forwards the request, and returns a single blended result page with no account and no tracking SearXNG documentation. This guide takes you from an empty server to a hardened, HTTPS-protected instance you (and maybe a few friends) can actually use every day Installation guide.
Image: SearXNG project (docs.searxng.org)
What you are actually standing up
SearXNG is a free, open-source meta-search engine and an actively maintained fork of the original Searx project. Rather than crawling the web itself, it fans a single query out to many search services — Google, Bing, Brave, Mojeek, Wikipedia, and a long tail of specialized engines — then merges and de-duplicates the results into one page Source repository. The privacy win is structural: upstream engines see a request coming from your server’s IP, not from every individual user, and SearXNG can forward no cookies, no identifiers, and (with the image proxy on) no referrer when thumbnails are fetched. You decide what is logged; by default a self-hosted instance keeps almost nothing.
The trade you accept is operational: you run the box, you apply updates, and if you open it to the public you become responsible for not letting it become an abuse relay for the upstream engines. None of that is hard, and the rest of this guide is the checklist.
Before you start
You need four things. A Linux host with Docker installed — a small VPS, a spare Raspberry Pi 4 or later, or an old mini-PC on your LAN all work; SearXNG is light. A domain name if you want clean HTTPS and remote access (a free subdomain from any DNS provider is fine). Ports 80 and 443 reachable from the internet if the instance is public, or just LAN access if it is for you alone. And about ten minutes of focused attention the first time.
You do not need to clone the source or build anything. The official image on Docker Hub is the supported path Docker Hub image. Pinning to a specific tag is wise for reproducibility, but latest is acceptable for a first run.
Step 1 — Get it running
Create a directory to hold your persistent config, then start the container. The image expects its settings at /etc/searxng inside the container, so you mount a local folder there:
mkdir -p ./searxng
docker run -d \
--name searxng \
-p 8080:8080 \
-v "${PWD}/searxng:/etc/searxng" \
-e SEARXNG_BASE_URL=http://localhost:8080/ \
searxng/searxng
On first boot the container generates a settings.yml and a random secret key for you, then listens on port 8080. Open http://<your-host>:8080 and you should see a working search page. If you only ever search from your own network, you can stop here — but most people want a proper domain and TLS, and everyone should tighten the settings before trusting it.
Step 2 — Harden settings.yml
Open ./searxng/settings.yml. A stock file uses use_default_settings: true, which inherits the project’s sane defaults; you only override what you care about. The lines worth touching first:
use_default_settings: true
general:
instance_name: "My SearXNG"
contact_url: "mailto:you@example.com"
server:
secret_key: "REPLACE_WITH_32_HEX_CHARS_FROM_OPENSL
bind_address: "127.0.0.1"
port: 8080
base_url: "https://search.example.com/"
image_proxy: true
limiter: true
search:
default_lang: ""
autocomplete: "duckduckgo"
Generate the secret with openssl rand -hex 32 and paste it in. Setting bind_address to 127.0.0.1 means the container only listens on the host loopback, so the internet cannot reach it directly — your reverse proxy (next step) is the only front door. image_proxy: true fetches result thumbnails through your server instead of letting the browser leak its IP to image hosts, and limiter: true turns on the built-in rate limiter, which matters the moment more than one person uses the box Settings reference.
Restart to apply: docker restart searxng.
Step 3 — Put it behind TLS
Exposing a raw HTTP search box to the world is sloppy and, on public networks, a privacy leak in its own right. The easy answer is Caddy, which obtains and renews a Let’s Encrypt certificate automatically:
search.example.com {
reverse_proxy localhost:8080
}
Run Caddy, point your DNS A/AAAA record at the host, and https://search.example.com/ should serve your instance. The server.base_url you set in Step 2 tells SearXNG to emit correct absolute links and redirects. If you prefer nginx, the same idea applies: terminate TLS at the proxy and proxy_pass to http://127.0.0.1:8080. Keep the container bound to loopback so only the proxy can talk to it.
Step 4 — Decide who it is for
A private instance for one person needs almost no policy. A public one is a different animal, because every query you forward carries your server’s IP to upstream engines, and a few abusive users can get that IP rate-limited or blocked for everyone. If you publish the URL, do at least these:
- Keep
limiter: trueand tune the tokens if you see errors from upstreams. - Write a one-paragraph privacy page and point
general.contact_urlat it, so users know what you keep (ideally: nothing). - Consider disabling engines that are aggressive about blocking datacenter IPs, or rotate which ones are on by default under the
engines:override. - Set a
robots.txtthat discourages search-engine crawlers from indexing a public instance, to avoid becoming a SEO spam vector.
None of this makes the instance “secret” — it makes it responsible. The SearXNG docs are explicit that public operators are stewards of shared upstream capacity, not just tenants.
Step 5 — Make it yours
The default engine set is broad. You can trim it or promote favorites in settings.yml under an engines: block, and you can use bangs at query time — typing !w quantum computing sends that query straight to Wikipedia, !gh to GitHub, and so on. Autocomplete is configurable (search.autocomplete), and the result page itself can be themed. Spend ten minutes here and the instance starts feeling like your search engine rather than a generic one.
For daily driving, add it as the default search in your browser by pointing the search engine URL at https://search.example.com/search?q=%s. On mobile, the same URL works as a custom search engine in most browsers that allow one.
Keeping it alive
Updates are a one-liner: docker pull searxng/searxng && docker rm -f searxng (your volume with settings.yml survives the recreate because it is mounted, not inside the container). Because config lives on the host, you can back it up with a single tar of the ./searxng folder. Watch the container logs (docker logs searxng) if results suddenly thin out — that usually means an upstream changed its response format, which the project fixes quickly in new image builds.
The point of all this
After an evening of setup you get a search box that does not profile you, does not auction your intent to advertisers, and does not trap your history behind an account you cannot export. That is a smaller, more durable freedom than it sounds, and it costs the price of a cheap VPS or the electricity of a Pi on the shelf. SearXNG is mature, the docs are current, and the container install removes almost all of the old friction of running it yourself SearXNG documentation. The only thing it cannot do is decide for you that owning your tools is worth ten minutes — so here is the nudge.