Self-Host SearXNG: Privacy-First Search Engine 2026
TL;DR
SearXNG is a self-hosted metasearch engine that aggregates results from 70+ search engines (Google, Bing, DuckDuckGo, Wikipedia, etc.) while keeping your searches private — no tracking, no profiling, no personalized filter bubbles. AGPL 3.0, ~17K GitHub stars. Deploy in 5 minutes with Docker. Point your browser to your own instance and search the web privately.
Key Takeaways
- SearXNG: AGPL 3.0, ~17K stars, Python, aggregates 70+ search engines
- Privacy: Your queries never reach Google with your IP — SearXNG proxies requests
- No filter bubble: Results aren't personalized to your browsing history
- Setup time: 5 minutes with Docker
- Use case: Personal privacy, family search server, avoiding Google/Bing profiling
- Cost: Server cost only (~$0 on a small VPS alongside other services)
Why Self-Host a Search Engine?
Google and Bing track everything:
- Every search query is logged with your IP and linked to your Google account
- Search history builds a profile used for ad targeting
- Results are personalized — you see what Google thinks you want to see (filter bubble)
- Data is kept indefinitely and can be used in legal proceedings
DuckDuckGo is better but not ideal:
- Doesn't track you, but results come primarily from Bing
- You still trust a third-party service with your queries
- Bing gets the queries (through DDG's relationship)
SearXNG gets you:
- Your queries stay on your server — never sent to Google with your IP
- SearXNG acts as a proxy: makes anonymous requests to Google/Bing on your behalf
- Aggregated results from 70+ sources — better coverage than any single engine
- Results aren't personalized — you get the "real" search results
Part 1: Docker Compose Setup
# docker-compose.yml
version: '3.8'
services:
searxng:
image: searxng/searxng:latest
container_name: searxng
restart: unless-stopped
ports:
- "8080:8080"
volumes:
- ./searxng:/etc/searxng:rw
environment:
- SEARXNG_BASE_URL=https://search.yourdomain.com/
- UWSGI_THREADS=4 # Increase for higher traffic
redis:
image: redis:7-alpine
restart: unless-stopped
command: redis-server --save "" --appendonly "no"
cap_drop:
- ALL
cap_add:
- SETGID
- SETUID
- DAC_OVERRIDE
# Create config directory and generate initial settings:
mkdir -p searxng
# Start to generate default config:
docker compose up -d
# SearXNG generates a settings.yml in ./searxng/ on first run
# Stop, configure, then restart:
docker compose down
Part 2: Configuration (settings.yml)
After the first run, ./searxng/settings.yml is created. Key settings to customize:
# searxng/settings.yml
use_default_settings: true
general:
debug: false
instance_name: "My Search"
privacypolicy_url: false
contact_url: false
enable_metrics: false # Don't track usage
server:
port: 8080
bind_address: "0.0.0.0"
secret_key: "your-secret-key-here" # Change this!
base_url: "https://search.yourdomain.com/"
image_proxy: true # Proxy images (prevents image tracking)
http_protocol_version: "1.1"
redis:
url: redis://redis:6379/0
ui:
static_use_hash: true
default_locale: "" # Empty = auto-detect
query_in_title: false
infinite_scroll: false
default_theme: simple
theme_args:
simple_style: dark # Dark mode!
search:
safe_search: 0 # 0=off, 1=moderate, 2=strict
autocomplete: "" # "google", "brave", "duckduckgo", "" (off)
default_lang: "auto"
ban_time_on_fail: 5 # Ban engine for 5 min if it fails
max_ban_time_on_fail: 120
# Configure which search engines to use:
engines:
- name: google
engine: google
shortcut: g
disabled: false
- name: bing
engine: bing
shortcut: b
disabled: false
- name: duckduckgo
engine: duckduckgo
shortcut: ddg
disabled: false
- name: brave
engine: brave
shortcut: brave
disabled: false
- name: wikipedia
engine: wikipedia
shortcut: wp
- name: github
engine: github
shortcut: gh
disabled: false
- name: stackoverflow
engine: stackoverflow
shortcut: so
disabled: false
- name: npm
engine: npm
shortcut: npm
disabled: false
- name: pypi
engine: pypi
shortcut: pypi
disabled: false
# Disable engines you don't want:
- name: yahoo
disabled: true
- name: yandex
disabled: true
Generate a Proper Secret Key
openssl rand -hex 32
# Add the output as your secret_key value
# Restart with new config:
docker compose up -d
Part 3: HTTPS with Caddy
search.yourdomain.com {
reverse_proxy localhost:8080
}
Or with Nginx:
server {
listen 443 ssl;
server_name search.yourdomain.com;
ssl_certificate /etc/letsencrypt/live/search.yourdomain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/search.yourdomain.com/privkey.pem;
location / {
proxy_pass http://localhost:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
Part 4: Set as Default Browser Search Engine
Chrome / Chromium / Brave
- Go to
https://search.yourdomain.comand wait a few seconds - Settings → Search engine → Manage search engines
- Your SearXNG instance should appear as "Other search engines"
- Click Make default next to it
Or add manually:
- Search engine name:
My SearXNG - Keyword:
s - URL:
https://search.yourdomain.com/search?q=%s
Firefox
- Visit
https://search.yourdomain.com - Click the search bar → click the SearXNG icon that appears at the bottom
- "Add SearXNG" → Set as default
Or via add-on: Firefox Multi-Account Containers with SearXNG.
Safari
Add as a custom search engine via Settings → Search → Add Search Engine.
Part 5: Using Search Bang Shortcuts
SearXNG supports bang shortcuts like DDG for searching specific sites:
!g python async await → Searches Google directly
!yt funny cats → Searches YouTube
!gh flask → Searches GitHub
!so error message → Searches Stack Overflow
!npm express → Searches npm
!wp machine learning → Searches Wikipedia
!a keyboard → Searches Amazon
!w google vs bing → Searches WolframAlpha
Part 6: Rate Limiting and Access Control
If you're running a private instance, restrict access:
Basic Auth via Nginx
location / {
proxy_pass http://localhost:8080;
auth_basic "Private Search";
auth_basic_user_file /etc/nginx/.htpasswd;
}
# Create user:
echo -n "user:" >> /etc/nginx/.htpasswd
openssl passwd -apr1 'password' >> /etc/nginx/.htpasswd
IP Allowlist (only your home network)
location / {
allow 1.2.3.4/32; # Your home IP
allow 192.168.0.0/24; # Local network
deny all;
proxy_pass http://localhost:8080;
}
Limit to Intranet (No Public Access)
# docker-compose.yml — only bind to localhost:
ports:
- "127.0.0.1:8080:8080" # Not accessible from outside
Then access via VPN or SSH tunnel from outside your network.
Privacy Features
Image Proxying
Enable in settings.yml (image_proxy: true) — images are fetched by SearXNG's server, not your browser. Prevents Google/other CDNs from knowing you viewed a search result's images.
No Logging
By default, SearXNG logs nothing about searches. Verify in your server logs:
docker compose logs searxng | grep -i "query\|search"
# Should show no query content in logs
Tor Integration (Advanced)
For maximum privacy, route SearXNG's outbound requests through Tor:
# Add to docker-compose.yml:
tor:
image: dperson/torproxy
restart: unless-stopped
ports:
- "9050:9050"
# In searxng/settings.yml:
outgoing:
proxies:
all://:
- socks5h://tor:9050 # Route all engine queries through Tor
Note: Tor makes searches significantly slower and some engines (Google) block Tor exit nodes.
Maintenance
# Update SearXNG:
docker compose pull
docker compose up -d
# Check if engines are working:
# Visit https://search.yourdomain.com/stats
# Shows which engines are failing or slow
# Clear Redis cache:
docker exec redis redis-cli FLUSHALL
SearXNG vs Alternatives
| Search | Type | Privacy | Index |
|---|---|---|---|
| SearXNG (self-hosted) | Metasearch | ✅ Complete | Aggregated |
| DuckDuckGo | Managed | ✅ Good | Bing-based |
| Brave Search | Managed | ✅ Good | Independent |
| Startpage | Managed | ✅ Good | Google proxy |
| Whoogle | Self-hosted | ✅ | Google only |
| Kagi | Managed/paid | ✅ | Independent |
Whoogle (simpler alternative): Only proxies Google results, simpler setup, no multi-engine aggregation.
Compare all open source privacy tools at OSSAlt.com/categories/privacy.