SearXNG: Privacy-Respecting Metasearch
Private search aggregating 70+ engines. Self-hosted Google alternative.
Introduction
SearXNG is a free, privacy-respecting metasearch engine that aggregates results from more than 70 search services without tracking or profiling users. As a fork of the original SearX project, SearXNG offers improved performance, modern features, and active development. It acts as a proxy between you and search engines, ensuring your searches remain private while delivering comprehensive results from multiple sources.
By the end of this guide, you’ll have a production-ready SearXNG installation that:
- Provides completely private and anonymous searching
- Aggregates results from Google, Bing, DuckDuckGo, and 70+ other engines
- Offers customizable search categories and engines
- Includes no tracking, ads, or data collection
- Features a clean, modern, and customizable interface
- Supports advanced search operators and filters
Prerequisites
Before starting, ensure you have:
- A Linux server with at least 1GB RAM (2GB recommended)
- Docker and Docker Compose installed
- Basic understanding of web services and privacy concepts
- At least 5GB free disk space
- Root or sudo access
- Optional: Domain name for public access
- Optional: Redis for caching (recommended for better performance)
What Makes SearXNG Special?
Key Features
Privacy First: No cookies, no tracking, no user profiling. Your searches are completely anonymous.
Metasearch Power: Aggregates results from multiple search engines, providing more comprehensive results than any single source.
Customizable Engines: Choose which search engines to use for different categories like general, images, videos, news, and more.
No Ads: Clean search results without advertisements or sponsored content.
Open Source: Fully transparent code that you can audit, modify, and self-host.
Advanced Features: Instant answers, autocomplete, bang shortcuts, custom themes, and more.
Multi-Language: Interface available in 60+ languages with international search engine support.
Why Self-Host SearXNG?
- Complete Control: You control which engines are used and how results are processed
- No Rate Limiting: Public instances often hit rate limits; your instance is just for you
- Custom Configuration: Tailor the experience to your specific needs
- Privacy Guarantee: Only you have access to your search patterns
- Browser Default: Set as your default search engine with full privacy
- Family/Team Use: Provide private search for your family or organization
Architecture Overview
Our setup consists of:
- SearXNG Container: Main search engine application
- Redis Container: Caching layer for improved performance
- Caddy/Nginx: Optional reverse proxy for HTTPS
- Filtron: Optional rate limiting (for public instances)
- Morty: Optional result proxy for extra privacy
The search flow:
- User submits a search query to SearXNG
- SearXNG queries multiple configured search engines in parallel
- Results are aggregated, deduplicated, and ranked
- Clean results are returned to the user without tracking
- Redis caches results for faster repeat queries
Directory Structure Setup
Create the necessary directory structure:
mkdir -p ~/searxng/{searxng,redis,caddy}
cd ~/searxng Generate Secret Key
Generate a secure secret key for SearXNG:
# Generate a random secret key
openssl rand -hex 32 Save this key for use in the configuration.
Docker Compose Configuration
Create a docker-compose.yml file:
version: '3.8'
services:
searxng:
container_name: searxng
image: searxng/searxng:latest
restart: unless-stopped
ports:
- "8080:8080"
volumes:
- ./searxng:/etc/searxng:rw
environment:
- SEARXNG_BASE_URL=https://search.yourdomain.com
- SEARXNG_SECRET_KEY=YOUR_SECRET_KEY_HERE
- SEARXNG_REDIS_URL=redis://redis:6379/0
networks:
- searxng_net
depends_on:
- redis
cap_drop:
- ALL
cap_add:
- CHOWN
- SETGID
- SETUID
logging:
driver: json-file
options:
max-size: "10m"
max-file: "3"
redis:
container_name: searxng_redis
image: redis:7-alpine
restart: unless-stopped
command: redis-server --save 30 1 --loglevel warning
volumes:
- ./redis:/data
networks:
- searxng_net
cap_drop:
- ALL
cap_add:
- SETGID
- SETUID
- DAC_OVERRIDE
networks:
searxng_net:
driver: bridge Important Notes:
- Replace
YOUR_SECRET_KEY_HEREwith the generated secret key - Update
SEARXNG_BASE_URLto your domain orhttp://localhost:8080for local use - Redis provides caching for better performance
- Containers run with minimal capabilities for security
SearXNG Configuration
Create the settings file ~/searxng/searxng/settings.yml:
use_default_settings: true
general:
debug: false
instance_name: "My SearXNG Instance"
privacypolicy_url: false
donation_url: false
contact_url: false
enable_metrics: false
brand:
new_issue_url: https://github.com/searxng/searxng/issues/new
docs_url: https://docs.searxng.org
public_instances: https://searx.space
wiki_url: https://github.com/searxng/searxng/wiki
issue_url: https://github.com/searxng/searxng/issues
search:
safe_search: 0 # 0=None, 1=Moderate, 2=Strict
autocomplete: "google" # Options: google, duckduckgo, wikipedia, etc.
default_lang: "en"
ban_time_on_fail: 5
max_ban_time_on_fail: 120
formats:
- html
- json
server:
port: 8080
bind_address: "0.0.0.0"
secret_key: "YOUR_SECRET_KEY_HERE" # Must match docker-compose
limiter: true
image_proxy: true
method: "GET"
http_protocol_version: "1.1"
redis:
url: redis://redis:6379/0
ui:
static_use_hash: true
default_locale: "en"
query_in_title: true
infinite_scroll: false
center_alignment: false
cache_url: https://web.archive.org/web/
default_theme: simple
theme_args:
simple_style: auto # auto, light, dark
# Enabled search categories
categories_as_tabs:
general:
images:
videos:
news:
map:
music:
it:
science:
files:
# Engine preferences
engines:
- name: google
engine: google
shortcut: go
use_mobile_ui: false
- name: duckduckgo
engine: duckduckgo
shortcut: ddg
- name: bing
engine: bing
shortcut: bi
- name: brave
engine: brave
shortcut: br
time_range_support: true
paging: true
- name: qwant
engine: qwant
shortcut: qw
categories: general
disabled: false
- name: wikipedia
engine: wikipedia
shortcut: wp
base_url: 'https://{language}.wikipedia.org/'
- name: youtube
engine: youtube_noapi
shortcut: yt
- name: github
engine: github
shortcut: gh
- name: stackoverflow
engine: stackoverflow
shortcut: st
- name: reddit
engine: reddit
shortcut: re
- name: docker hub
engine: docker_hub
shortcut: dh
categories: it
- name: arxiv
engine: arxiv
shortcut: arx
categories: science
- name: openstreetmap
engine: openstreetmap
shortcut: osm
categories: map
- name: wikidata
engine: wikidata
shortcut: wd
categories: general
- name: google images
engine: google_images
shortcut: goi
categories: images
- name: bing images
engine: bing_images
shortcut: bii
categories: images
- name: google news
engine: google_news
shortcut: gon
categories: news
- name: piped
engine: piped
shortcut: pp
categories: videos
enabled_plugins:
- 'Hash plugin'
- 'Search on category select'
- 'Self Information'
- 'Tracker URL remover'
- 'Ahmia blacklist'
disabled_plugins:
- 'Hostname replace'
# Security and privacy settings
outgoing:
request_timeout: 3.0
max_request_timeout: 15.0
pool_connections: 100
pool_maxsize: 20
enable_http2: true
verify: true
max_redirects: 5
retries: 1
proxies:
http: null
https: null
source_ips:
- 0.0.0.0 Important: Replace YOUR_SECRET_KEY_HERE with your generated secret key.
Starting SearXNG
Start the containers:
cd ~/searxng
docker compose up -d Verify containers are running:
docker compose ps
docker compose logs -f searxng Access SearXNG:
- Open your browser to
http://localhost:8080 - You should see the SearXNG interface
Customizing Search Engines
Edit ~/searxng/searxng/settings.yml to enable/disable engines:
engines:
# Disable an engine
- name: google
engine: google
disabled: true # Add this line
# Add custom engine weights (prefer certain sources)
- name: duckduckgo
engine: duckduckgo
weight: 1.5 # Results ranked higher
# Configure time range support
- name: brave
engine: brave
time_range_support: true
time_range_map:
day: 'day'
week: 'week'
month: 'month'
year: 'year'
# Add custom headers for rate limit avoidance
- name: google
engine: google
use_mobile_ui: true # Use mobile version to avoid blocks Restart after changes:
docker compose restart searxng Setting Browser Default Search
Firefox
- Navigate to your SearXNG instance
- Click the address bar
- Click the “Add Search Engine” option
- Go to Firefox Settings > Search
- Set SearXNG as default
Chrome/Chromium
- Go to Settings > Search engine > Manage search engines
- Click “Add”
- Fill in:
- Name:
SearXNG - Keyword:
searxng - URL:
http://localhost:8080/?q=%s
- Name:
- Click the three dots and select “Make default”
Manually Add OpenSearch
Create ~/searxng/searxng/opensearch.xml:
<?xml version="1.0" encoding="UTF-8"?>
<OpenSearchDescription xmlns="http://a9.com/-/spec/opensearch/1.1/">
<ShortName>SearXNG</ShortName>
<Description>Privacy-respecting metasearch engine</Description>
<InputEncoding>UTF-8</InputEncoding>
<Image width="64" height="64" type="image/png">https://search.yourdomain.com/static/themes/simple/img/searxng.png</Image>
<Url type="text/html" method="get" template="https://search.yourdomain.com/?q={searchTerms}"/>
<Url type="application/x-suggestions+json" method="get" template="https://search.yourdomain.com/autocompleter">
<Param name="q" value="{searchTerms}"/>
</Url>
</OpenSearchDescription> Bang Shortcuts
SearXNG supports bang shortcuts (like DuckDuckGo):
!go query- Search Google!ddg query- Search DuckDuckGo!yt query- Search YouTube!gh query- Search GitHub!wp query- Search Wikipedia!st query- Search Stack Overflow!red query- Search Reddit!osm query- Search OpenStreetMap
Example: !gh docker compose searches GitHub for “docker compose”
Theme Customization
SearXNG includes several themes:
ui:
default_theme: simple # Options: simple, oscar, pix-art
theme_args:
simple_style: dark # auto, light, dark Or create custom CSS in ~/searxng/searxng/custom.css:
/* Custom theme colors */
:root {
--color-base-font: #ffffff;
--color-base-background: #0d1117;
--color-header-background: #161b22;
--color-footer-background: #161b22;
--color-sidebar-background: #161b22;
--color-backtotop-background: #58a6ff;
--color-backtotop-font: #ffffff;
} Reference in settings:
ui:
static_path: /etc/searxng
custom_css: custom.css Reverse Proxy with Caddy
Create ~/searxng/Caddyfile:
search.yourdomain.com {
reverse_proxy searxng:8080
# Security headers
header {
Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
X-Content-Type-Options "nosniff"
X-Frame-Options "DENY"
Referrer-Policy "no-referrer"
Permissions-Policy "geolocation=(), microphone=(), camera=()"
}
# Rate limiting (optional)
rate_limit {
zone searxng {
key {remote_host}
events 100
window 1m
}
}
} Update docker-compose.yml:
services:
caddy:
container_name: searxng_caddy
image: caddy:latest
restart: unless-stopped
ports:
- "80:80"
- "443:443"
volumes:
- ./Caddyfile:/etc/caddy/Caddyfile:ro
- ./caddy/data:/data
- ./caddy/config:/config
networks:
- searxng_net Nginx Alternative
Or use Nginx:
server {
listen 80;
server_name search.yourdomain.com;
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl http2;
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;
# Security headers
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-Frame-Options "DENY" always;
add_header Referrer-Policy "no-referrer" always;
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;
# Rate limiting
limit_req zone=searxng burst=20 nodelay;
limit_req_status 429;
}
# Static files caching
location /static {
proxy_pass http://localhost:8080;
proxy_cache_valid 200 1d;
expires 1d;
add_header Cache-Control "public, immutable";
}
}
# Rate limit zone (add to http block in nginx.conf)
limit_req_zone $binary_remote_addr zone=searxng:10m rate=10r/s; Performance Tuning
Optimize for better performance:
Redis Configuration
Create ~/searxng/redis/redis.conf:
# Memory optimization
maxmemory 256mb
maxmemory-policy allkeys-lru
# Persistence
save 900 1
save 300 10
save 60 10000
# Performance
tcp-backlog 511
timeout 0
tcp-keepalive 300 Update docker-compose.yml:
redis:
command: redis-server /usr/local/etc/redis/redis.conf
volumes:
- ./redis:/data
- ./redis/redis.conf:/usr/local/etc/redis/redis.conf:ro SearXNG Optimization
# In settings.yml
outgoing:
request_timeout: 2.0 # Faster timeout
pool_connections: 200 # More connections
pool_maxsize: 50
enable_http2: true # HTTP/2 for speed
server:
limiter: true # Enable rate limiting
image_proxy: true # Proxy images for privacy API Usage
SearXNG provides a JSON API:
# Basic search
curl "http://localhost:8080/search?q=docker&format=json"
# Search with category
curl "http://localhost:8080/search?q=homelab&category_general=1&format=json"
# Image search
curl "http://localhost:8080/search?q=kubernetes&category_images=1&format=json"
# Paginated results
curl "http://localhost:8080/search?q=docker&pageno=2&format=json" Example response:
{
"query": "docker",
"number_of_results": 150000000,
"results": [
{
"url": "https://www.docker.com/",
"title": "Docker: Empowering App Development",
"content": "Docker is a platform for developers...",
"engine": "google",
"parsed_url": ["https", "www.docker.com", "/", "", "", ""],
"template": "default.html",
"engines": ["google", "bing"],
"positions": [1, 2],
"score": 1.5
}
],
"suggestions": ["docker compose", "docker tutorial"],
"infoboxes": []
} Monitoring and Logs
Check SearXNG logs:
# View live logs
docker compose logs -f searxng
# Check Redis logs
docker compose logs -f redis
# View last 100 lines
docker compose logs --tail=100 searxng Enable metrics in settings:
general:
enable_metrics: true Access metrics at: http://localhost:8080/stats
Backup Configuration
Create a backup script:
#!/bin/bash
# ~/searxng/scripts/backup.sh
BACKUP_DIR=~/searxng/backups
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
BACKUP_FILE="$BACKUP_DIR/searxng_backup_$TIMESTAMP.tar.gz"
mkdir -p "$BACKUP_DIR"
echo "Creating backup..."
tar -czf "$BACKUP_FILE" ~/searxng/searxng/settings.yml ~/searxng/docker-compose.yml ~/searxng/Caddyfile
# Keep only last 10 backups
ls -t "$BACKUP_DIR"/searxng_backup_*.tar.gz | tail -n +11 | xargs -r rm
echo "Backup completed: $BACKUP_FILE" Troubleshooting
No Search Results
# Check if engines are enabled
docker compose exec searxng cat /etc/searxng/settings.yml | grep -A5 "engines:"
# Test specific engine
curl "http://localhost:8080/search?q=test&engines=duckduckgo&format=json"
# Check engine status
# Visit: http://localhost:8080/stats/checker Rate Limited by Search Engines
# Use mobile user agents
engines:
- name: google
use_mobile_ui: true
# Add delays between requests
outgoing:
request_timeout: 3.0
retries: 2 High Memory Usage
# Check container memory
docker stats searxng redis
# Reduce Redis memory
# In redis.conf:
maxmemory 128mb Slow Search Performance
# Enable HTTP/2
# In settings.yml:
outgoing:
enable_http2: true
# Reduce timeout
outgoing:
request_timeout: 2.0
# Check Redis connection
docker compose exec searxng redis-cli -h redis ping Container Restart Loop
# Check logs for errors
docker compose logs searxng
# Validate settings.yml
docker compose exec searxng cat /etc/searxng/settings.yml
# Check permissions
ls -la ~/searxng/searxng/ Security Hardening
Restrict Public Access
For private instances, use authentication:
# In Nginx config
location / {
auth_basic "Restricted Access";
auth_basic_user_file /etc/nginx/.htpasswd;
proxy_pass http://localhost:8080;
} Generate password:
sudo apt install apache2-utils
htpasswd -c /etc/nginx/.htpasswd yourusername Firewall Rules
# Only allow local access
sudo ufw allow from 192.168.1.0/24 to any port 8080
# Or use SSH tunnel
ssh -L 8080:localhost:8080 user@your-server Disable Logging
# In settings.yml
server:
access_log: false
# In docker-compose.yml
logging:
driver: "none" Advanced Features
Custom Result Filters
# Filter out certain domains
engines:
- name: google
engine: google
exclude_domains:
- pinterest.com
- facebook.com Language Preferences
search:
default_lang: "en"
languages:
- en
- fr
- de
- es Auto-Redirect
Automatically redirect to first result:
enabled_plugins:
- 'Self Information'
- 'Tracker URL remover'
- 'Ahmia blacklist'
- 'Autoredirect' # Add this Conclusion
You now have a fully functional, privacy-respecting SearXNG metasearch engine. Your searches are completely private, with no tracking or data collection, while still delivering comprehensive results from multiple search engines.
For more advanced configurations, explore:
- Public instance setup with Filtron rate limiting
- Custom engine integration
- Search result ranking customization
- Multi-user authentication
- Advanced privacy plugins
Enjoy your private search experience!