Kituwa IT · Self-hosting guides

Install SearXNG with Docker Compose

Private self-hosted metasearch

metasearchprivacyself-hosted

SearXNG is a metasearch engine: one box, many search engines, no tracking, no profiling, no third-party cookies. The same query fans out to Google, Bing, Brave, Wikipedia, Stack Overflow and dozens more, and returns one clean, neutral results page.

Category
Network & proxy
License
AGPL-3.0
Needs
Nothing
Image
searxng/searxng

What it is

A single-page search interface over a configured set of engines. Because every query originates from your server, the search engines see one client instead of a fingerprintable population, and you get results without ad injection. There's also a JSON API, which is what makes it useful as a backend.

Before you start

  • The stock settings will get you rate-limited or blocked within days. Making the outgoing traffic look like a normal browser is a configuration task, not a default.
  • Decide whether it's public. An open instance on the internet gets scraped and used to launder traffic to search engines within about a week.
  • Redis is optional but strongly recommended. Without it, SearXNG can't deduplicate concurrent identical requests and a burst of traffic hammers the upstream engines.

1 — Write the settings file first

Command / configuration
mkdir -p ~/services/searxng
cd ~/services/searxng

cat > settings.yml <<'EOF'
use_default_settings: true
general:
  instance_name: "my search"
  debug: false

server:
  secret_key: "CHANGE_ME_48_random_chars"
  limiter: true
  image_proxy: true
  bind_address: "0.0.0.0"
  port: 8080

search:
  safe_search: 1
  autocomplete: "duckduckgo"
  default_lang: "en"

outgoing:
  request_timeout: 5.0
  max_request_timeout: 10.0
  pool_connections: 100
  pool_maxsize: 20
  enable_http2: true

engines:
  - name: google
    disabled: false
  - name: duckduckgo
    disabled: false
  - name: brave
    disabled: false
  - name: wikipedia
    disabled: false
  - name: stackexchange
    disabled: false
EOF

2 — Write the compose file

Command / configuration
services:
  searxng:
    image: searxng/searxng:latest
    container_name: searxng
    restart: unless-stopped
    ports:
      - "127.0.0.1:8080:8080"
    volumes:
      - ./searxng:/etc/searxng
      - ./searxng-data:/var/cache/searxng
    environment:
      SEARXNG_BASE_URL: https://search.example.com/
      INSTANCE_NAME: my search
    cap_drop:
      - ALL
    cap_add:
      - CHOWN
      - SETGID
      - SETUID
    healthcheck:
      test: ["CMD", "wget", "--spider", "-q", "http://localhost:8080/"]
      interval: 30s
      timeout: 5s
      retries: 3

  valkey:
    image: valkey/valkey:8-bookworm
    container_name: searxng-valkey
    restart: unless-stopped
    volumes:
      - ./valkey:/data
    healthcheck:
      test: ["CMD", "valkey-cli", "ping"]
      interval: 30s
      timeout: 5s
      retries: 3

SearXNG needs write access to its own config directory. The cap_drop/cap_add combination is the official recommendation — dropping all capabilities and adding back only what it needs is what lets the searxng user chown its cache without running as root.

3 — Start it

Command / configuration
docker compose up -d
docker compose logs -f searxng | grep -i "started\|error"

4 — First-run setup

  1. Open https://search.example.com and run a test search. If every engine returns nothing, it's a rate limit, not a bug.
  2. Check Preferences → Engines and enable the ones you want. Google's JSON API has long since been shut down, so the "google" engine scrapes — functional, but fragile.
  3. Set an outbound proxy or rotate the User-Agent if you're being blocked. Persistent 403s from one engine mean that specific engine needs to go.
  4. Enable the limiter and keep it on. It stops a single client from running thousands of queries and getting your whole instance banned upstream.
  5. Use the JSON API for scripted queries: curl -s "https://search.example.com/search?q=nextcloud&format=json".

5 — Keep it private

Do not expose an open SearXNGPublic instances are routinely used as a proxy for scraping search results, and the upshot is your IP gets rate-limited by every engine. Keep it behind auth, behind Tailscale, or restrict access at the reverse proxy. If it must be public, treat the limiter as non-negotiable and expect it to break.

Help when you need it

Want help getting this running?

We can help with a supported Linux host, application setup, migration or troubleshooting. Contact us to confirm the software, scope and scheduling before ordering.

Related guides

← Browse all 30 guides · Back to top