SSD Nodes Learn Hosting plans →
تعلیمی Matt Connorتحریر: Matt Connor · اپ ڈیٹ شدہ 2026-09-05

SearXNG کو اپنے VPS پر نجی search engine بنائیں

Docker Compose کے ساتھ SearXNG چلائیں: settings.yml، limiter، TLS والا nginx، اور JSON search API ترتیب دیں تاکہ آپ کے scripts براہ راست query بھیج سکیں۔

آپ کیا بنا رہے ہیں

SearXNG کو self-host کرنے سے آپ کو ایک نجی search engine ملتا ہے جو آپ کے اپنے server پر چلتا ہے۔ SearXNG ایک metasearch engine ہے۔ یہ آپ کی query کو Google، Bing، DuckDuckGo اور Wikipedia جیسے دوسرے engines کو بھیجتا ہے، پھر موصول ہونے والے نتائج کو ایک result page میں یکجا کر دیتا ہے۔ کوئی profile نہیں بنائی جاتی اور کوئی tracking cookie set نہیں کی جاتی، کیونکہ آپ کی query محفوظ رکھنے والی واحد machine آپ کی اپنی ہے۔ اگر آپ کو کسی ایسی چیز کے بارے میں پرانی guides ملی ہیں جسے صرف Searx کہا جاتا ہے، تو یہ project اسی سے fork ہوا تھا، اور اس میں 2023 کے بعد کوئی commit نہیں ہوا۔ اس لیے دونوں کی حالت جانچ لیں، پھر کسی ایک guide پر عمل کریں۔

یہ stack چھوٹا ہے۔ دو containers، ایک settings file، اور ایک reverse proxy کافی ہیں۔ یہ ایک چھوٹے VPS پر آسانی سے چل جائے گا۔ تاہم ہر self-hosted service کے لیے ایسا نہیں ہوتا۔ PhotoPrism اور Immich کا موازنہ کرنے والی photo libraries میں RAM کی کم از کم ضرورت web app کے بجائے indexer طے کرتا ہے۔ اصل فیصلہ یہ ہے کہ instance نجی ہو، یعنی صرف آپ اور آپ کے اپنے scripts اس تک رسائی حاصل کریں، یا public ہو، یعنی internet پر موجود کوئی بھی شخص اس سے query کر سکے۔ یہ انتخاب security settings تبدیل کر دیتا ہے، اس لیے کچھ بھی type کرنے سے پہلے فیصلہ کر لیں۔ Default جواب نجی ہے۔

اسے چلانے کی ایک دوسری وجہ بھی ہے۔ SearXNG instance JSON میں response دیتا ہے۔ اس لیے آپ کا لکھا ہوا کوئی بھی script یا AI agent اپنی ملکیت کی search API حاصل کر لیتا ہے، جس کے لیے key، فی query billing یا quota سے متعلق کوئی email درکار نہیں ہوتی۔

Docker Compose کے ساتھ SearXNG انسٹال کریں

یہ project ایک container image اور Compose file جاری کرتا ہے۔ دونوں کو ایک نئے Ubuntu 24.04 server پر حاصل کریں، جس پر پہلے ہی Docker Engine اور Compose plugin موجود ہوں۔ اگر Docker آپ کے لیے نیا ہے تو VPS پر Docker Compose کی بنیادی باتیں سے شروع کریں اور پھر واپس آئیں۔

sudo install -d -o "$USER" -g "$USER" -m 750 /opt/searxng
cd /opt/searxng
mkdir -p core-config
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 -i .env.example .env

Compose file میں دو services بیان کی گئی ہیں۔ core خود SearXNG ہے، جبکہ valkey ایک in-memory data store ہے جو rate limiting اور مختصر مدت کے state کے لیے استعمال ہوتا ہے۔ یہ ./core-config/ کو container کے اندر /etc/searxng/ پر mount کرتا ہے، اس لیے آپ جو کچھ configure کرتے ہیں وہ host پر اسی ایک directory میں محفوظ رہتا ہے۔

اب .env میں ترمیم کریں۔ فراہم کردہ example کی ہر line comment کی گئی ہے، اسی لیے container ہر address پر port 8080 پر start ہوتا ہے۔ ان تینوں settings کو uncomment کریں اور values مقرر کریں۔

SEARXNG_VERSION=latest
SEARXNG_HOST=127.0.0.1
SEARXNG_PORT=8080

SEARXNG_HOST=127.0.0.1 اہم setting ہے۔ یہ published port کو 127.0.0.1:8080:8080 بناتی ہے، [::]:8080:8080 نہیں، اس لیے container صرف loopback address پر جواب دیتا ہے اور internet اس تک براہ راست نہیں پہنچ سکتا۔ اسے چھوڑنے سے container start ہوتے ہی exposed ہو جاتا ہے، کیونکہ published Docker port آپ کے firewall rules سے پہلے insert کی جاتی ہے۔ اس مسئلے کی مکمل وضاحت یہاں پڑھیں: published Docker ports ufw کو bypass کرتی ہیں۔

SEARXNG_VERSION=latest سیکھنے کے دوران مناسب ہے۔ جس server کی آپ کو واقعی فکر ہو، وہاں tag کو pin کریں۔ July 2026 تک release tags تاریخ پر مبنی ہیں اور 2026.3.25-541c6c3cb کی طرح دکھائی دیتے ہیں، اس لیے pinned deployment اسی وقت upgrade ہوتی ہے جب آپ فیصلہ کریں، نہ کہ اس وقت جب registry میں تبدیلی ہو۔ یہی اصول machine پر چلنے والی دیگر طویل مدتی services کے لیے بھی مفید ہے۔ اسی وجہ سے self-hosted RustDesk relay بھی اپنے image tags کو pin کرتا ہے: remote access service میں unattended upgrade بدترین وقت پر اپنی موجودگی ظاہر کر سکتا ہے۔

settings.yml: اہم حصے

پہلی بار start کرنے سے پہلے core-config/settings.yml بنائیں۔ use_default_settings: true SearXNG کو پہلے اس کے اپنے shipped defaults load کرنے اور پھر صرف آپ کی لکھی ہوئی keys apply کرنے کا بتاتا ہے۔ اس طرح فائل مختصر رہتی ہے اور نئی options شامل ہونے والی upgrades کے بعد بھی برقرار رہتی ہے۔

پہلے secret generate کریں، کیونکہ اس کی value براہِ راست فائل میں جائے گی۔

openssl rand -hex 32
use_default_settings: true

general:
  instance_name: "search.example.com"

server:
  base_url: "https://search.example.com/"
  secret_key: "paste-the-openssl-output-here"
  limiter: false
  public_instance: false
  image_proxy: true

valkey:
  url: valkey://valkey:6379/0

search:
  safe_search: 0
  autocomplete: "duckduckgo"
  formats:
    - html
    - json

secret_key session اور token data پر دستخط کرتا ہے۔ shipped default literal string ultrasecretkey ہے، اور اسے برقرار رکھنے کا مطلب ہے کہ جس شخص کو یہ default معلوم ہو، وہ ان tokens کو forge کر سکتا ہے۔ اسے ایک بار replace کریں، پھر تبدیل نہ کریں: بعد میں اسے بدلنے سے تمام saved preferences ضائع ہو جاتی ہیں۔

base_url public HTTPS address ہونا چاہیے، اور اس کے آخر میں trailing slash بھی ہونا چاہیے۔ SearXNG rendered links میں یہی address لکھتا ہے۔ اسے localhost پر رکھنے سے remote browser میں "next page" link قاری کی اپنی machine کی طرف point کرے گا اور ناکام ہو جائے گا۔

formats طے کرتا ہے کہ web endpoint کون سے output types فراہم کرے گا۔ json default list میں شامل نہیں ہے، اس لیے اسے add کرنے تک JSON request 403 واپس کرتی ہے۔ image_proxy: true result thumbnails کو آپ کے server کے ذریعے route کرتا ہے، اس لیے ان images کو host کرنے والی sites آپ کے visitors کے addresses نہیں دیکھتیں۔

valkey.url hostname valkey استعمال کرتا ہے، کیونکہ Compose file میں service کا نام یہی ہے، اور Compose دونوں containers کو ایک ہی network پر رکھتا ہے جہاں service names resolve ہوتے ہیں۔ اسے localhost پر point کرنے سے limiter ناکام ہو جاتا ہے، کیونکہ core container کے اندر localhost سے مراد وہی container ہوتا ہے۔

secret ایک plain file میں موجود ہے، اس لیے خود file کے بجائے اس کے اردگرد موجود directory کو protect کریں۔ chmod 750 /opt/searxng دوسرے host users کو باہر رکھتا ہے۔ core-config/settings.yml کو mode 600 پر tighten نہ کریں: container اپنے unprivileged user کے طور پر چلتا ہے، اور جس file کو وہ read نہ کر سکے، وہ SearXNG کو بالکل start نہیں ہونے دیتی۔

Stack start کریں اور اسے check کریں۔

cd /opt/searxng
docker compose up -d
docker compose ps
curl -I http://127.0.0.1:8080/

docker compose ps کو دونوں containers کی state running دکھانی چاہیے۔ curl کو HTTP/1.1 200 OK کا جواب دینا چاہیے۔ اگر یہ کوئی جواب نہ دے تو docker compose logs core پڑھیں، کیونکہ settings.yml میں YAML کی غلطی وہاں line کا نام بتانے والے parse error کے طور پر ظاہر ہوتی ہے۔

TLS کے ساتھ اسے nginx کے پیچھے رکھیں

Container صرف loopback پر listen کرتا ہے، اس لیے nginx اسے قابلِ رسائی بناتا ہے۔ یہی transport layer security (TLS) بھی شامل کرتا ہے۔ /etc/nginx/sites-available/searxng لکھیں۔

server {
    listen 80;
    server_name search.example.com;

    location / {
        proxy_pass http://127.0.0.1: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;
    }
}
sudo ln -s /etc/nginx/sites-available/searxng /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx
sudo certbot --nginx -d search.example.com

Reload کرنے سے پہلے nginx -t، syntax is ok اور test is successful دکھاتا ہے۔ Certbot اسی file کو دوبارہ لکھ کر certificate کے ساتھ 443 پر listen کرتا ہے اور port 80 سے redirect بھی شامل کرتا ہے۔ search.example.com کے لیے DNS record پہلے ہی اس server کی طرف point کرنا چاہیے، کیونکہ certificate authority HTTP کے ذریعے ایک file fetch کرکے ملکیت کی تصدیق کرتی ہے۔ مکمل طریقہ، جس میں renewal بھی شامل ہے، Ubuntu 24.04 کے لیے Certbot اور nginx گائیڈ میں موجود ہے۔

یہ دونوں forwarding headers محض ظاہری سجاوٹ نہیں ہیں۔ X-Forwarded-For اور X-Real-IP کے بغیر SearXNG تک پہنچنے والی ہر request میں proxy address شامل ہوتا ہے۔ اس لیے rate limiter تمام traffic کو ایک ہی client کی طرف سے آنے والا سمجھتا ہے اور visitors میں فرق نہیں کر پاتا۔

اسکرپٹس اور ایجنٹس JSON search API کیوں چاہتے ہیں

json کو formats کے ساتھ استعمال کرنے پر، صفحہ دکھانے والا یہی endpoint structured data واپس کرتا ہے۔

curl -s 'http://127.0.0.1:8080/search?q=wireguard+mtu&format=json' \
  | jq -r '.results[0:5][] | .url'

آپ کو ایک object واپس ملتا ہے جس میں results array ہوتا ہے۔ ہر entry میں url، title، content اور اسے فراہم کرنے والا engine شامل ہوتا ہے، جبکہ answers، infoboxes اور suggestions بھی موجود ہوتے ہیں۔ یہ کسی summariser، link checker یا research loop کو data دینے کے لیے کافی ہے۔ ان نتائج کو language model کے حوالے کرنا بظاہر نظر آنے سے زیادہ بڑا قدم ہے، کیونکہ search results غیر معتبر متن ہوتے ہیں اور ان میں اپنی ہدایات شامل ہو سکتی ہیں۔ AI agent کو اپنی SearXNG instance سے جوڑنا اسی مسئلے کو تفصیل سے حل کرتا ہے۔

یہ agent پر مبنی ہر کام کے لیے اہم ہے۔ language model کی training cutoff ہوتی ہے، اس لیے موجودہ حالات سے متعلق سوالات کے جواب دینے کے لیے اسے live search درکار ہوتی ہے۔ تجارتی search APIs ہر query کی فیس لیتی ہیں اور rate limit بھی سخت رکھتی ہیں۔ مقامی instance اس server پر ایک container کی لاگت پر چلتی ہے جس کی ادائیگی آپ پہلے ہی کر رہے ہیں، اور queries کبھی اس سے باہر نہیں جاتیں۔ اگر آپ کسی model میں tools شامل کر رہے ہیں تو یہی منطق VPS پر MCP servers چلانے پر بھی لاگو ہوتی ہے، جہاں search tool عموماً پہلا tool ہوتا ہے جسے لوگ شامل کرتے ہیں۔

API استعمال کرنے کے لیے 2 اصول ہیں۔ instance کو private رکھیں۔ API side کو loopback address یا private network پر bind کریں اور صرف اپنے hosts کو اس تک رسائی دیں۔ پھر queries محتاط رفتار سے بھیجیں۔ SearXNG آپ کی request حقیقی search engines کو forward کرتا ہے، اس لیے اگر کوئی script ہر سیکنڈ میں 100 queries چلائے تو وہ Google سے آپ کے server کو block کرنے کی درخواست کر رہی ہے۔

Limiter اور public instance کے لیے مختلف تبدیلیاں

Limiter، SearXNG کا bot defence نظام ہے۔ یہ request headers، addresses اور request rates کی نگرانی کرتا ہے اور ایسی network traffic کو خارج کر دیتا ہے جو automated معلوم ہو۔ اسے یہ state محفوظ رکھنے کے لیے Valkey درکار ہوتا ہے، اسی لیے Compose file میں یہ شامل ہے۔

Private instance پر limiter: false رکھیں۔ آپ کی اپنی scripts تعریف کے مطابق automated traffic ہیں، اس لیے limiter عین وہ JSON calls block کر دے گا جن کے لیے آپ نے instance بنایا ہے۔ اس کے بجائے access control reverse proxy کی ذمہ داری ہے: nginx location میں allow اور deny کی جوڑی، HTTP basic authentication، یا ایسا firewall جو صرف آپ کے دوسرے servers کو اجازت دے۔ اگر آپ کو مختلف networks کے درمیان منتقل ہونے والے laptop سے private instance تک پہنچنا ہو تو اس کے سامنے v3 onion address رکھنا چوتھا طریقہ ہے، کیونکہ Tor کسی نئی چیز کو internet پر ظاہر کیے بغیر اسی loopback port سے connect ہو جاتا ہے۔

اگر آپ instance کو دوسرے لوگوں کے لیے public کریں تو دونوں switches on کر دیں۔

server:
  limiter: true
  public_instance: true

مزید باریک control core-config/limiter.toml میں موجود ہے، جسے container /etc/searxng/limiter.toml سے پڑھتا ہے۔ صرف وہی keys لکھیں جنہیں آپ تبدیل کرنا چاہتے ہیں۔ Proxy کے پیچھے آپ کو proxy declare کرنا ضروری ہے، ورنہ limiter آپ کے nginx address کو abusive client سمجھ لے گا۔

[botdetection]
trusted_proxies = [
  '127.0.0.0/8',
  '::1',
]

[botdetection.ip_limit]
link_token = true

link_token = true SearXNG کو ایسا token جاری کرنے پر مجبور کرتا ہے جسے صرف ایک حقیقی browser session fetch کرے گا۔ اس سے زیادہ تر سادہ scrapers رک جاتے ہیں۔ توقع رکھیں کہ public instance چند دنوں میں ان کی توجہ حاصل کر لے گا۔ Engine errors کی بھی توقع رکھیں، کیونکہ آپ جتنی زیادہ traffic forward کریں گے، upstream engines اتنی جلد آپ کے server address کو CAPTCHAs بھیجنا شروع کر دیں گے۔ Public SearXNG instance کی دیکھ بھال مسلسل کام ہے۔ Private instance کے لیے ایسا نہیں ہے، اسی لیے یہ 2026 میں self-host کرنے کے قابل چیزوں کی زیادہ تر مختصر فہرستوں میں شامل ہوتا ہے۔ ان فہرستوں کا ہر اندراج infrastructure بھی نہیں ہوتا: Jellyfin library کو walkable 90s rental store کے طور پر دوبارہ بنانا بھی اسی nginx block کے پیچھے ایک ہی container ہے، جسے کسی workflow کے بجائے شام کے وقت کے استعمال کے لیے configure کیا گیا ہے۔

تلاشوں کا کوئی نتیجہ کیوں نہیں آتا

اپنے instance پر /stats کھولیں۔ اس میں ہر engine کی error rate اور response time درج ہوتی ہے۔ جب نتائج کم محسوس ہوں تو سب سے پہلے یہی دیکھیں۔

جس engine کے ساتھ "Access denied" یا "CAPTCHA" errors دکھائی دیں، اس نے آپ کے server address کو block کر دیا ہے۔ Data centre ranges میں شامل addresses کے لیے یہ عام بات ہے، کیونکہ search engines فرض کرتے ہیں کہ یہ scrapers سے متعلق ہیں۔ اس کے بعد SearXNG ناکام engine کو دوبارہ کوشش کرنے کے بجائے کچھ مدت کے لیے suspend کر دیتا ہے، اس لیے ایک blocked engine خاموشی سے آپ کے results سے خارج ہو جاتا ہے۔ اسے settings.yml میں disable کریں یا اس کمی کو قبول کریں۔ یہ صرف دو ہی اختیارات نہیں ہیں، کیونکہ کچھ CAPTCHA blocks کا ایسا حل موجود ہے جو restart کے بعد بھی برقرار رہتا ہے۔ باقی engines پھر بھی جواب دیتے رہتے ہیں۔ 429 مبہم صورت ہے، کیونکہ یہ آپ کے اپنے limiter کی طرف سے آ سکتا ہے یا upstream engine آپ کے server کو reject کر رہا ہو سکتا ہے، اور settings تبدیل کرنے سے پہلے log line بتاتی ہے کہ ان دونوں میں سے کون سی صورت ہے۔

اگر تمام engines ایک ہی وقت میں fail ہوں تو container میں outbound name resolution کام نہیں کر رہی یا internet تک route موجود نہیں۔ یہ test container کے اندر سے کریں۔

docker compose exec core wget -qO- https://duckduckgo.com > /dev/null && echo ok

Box پر کوئی چیز آپ کو یہ نہیں بتائے گی کہ یہ check کب fail ہونا شروع ہوا۔ اس لیے اسے cron سے چلائیں اور failure کو اپنے ntfy server سے اپنے phone پر alert بھیجنے دیں، بجائے اس کے کہ نتائج کم ہونے کا خود محسوس ہونے تک انتظار کریں۔

FAQ

کیا SearXNG میری تلاشوں کو گمنام بناتا ہے؟

یہ ان engines سے آپ کی شناخت چھپا دیتا ہے جن سے یہ query کرتا ہے، کیونکہ ان engines کو درخواست آپ کے browser کے بجائے آپ کے server سے آتی ہوئی دکھائی دیتی ہے۔ یہ query آپ کے server سے نہیں چھپاتا، اور نہ ہی آپ کے server کو ان engines سے چھپاتا ہے۔ Single-user instance میں اس address سے آنے والا تمام traffic آپ کا ہوتا ہے، اس لیے خود address ہی شناخت کنندہ بن جاتا ہے۔ آپ کے browser اور instance کے درمیان traffic کو TLS certificate محفوظ رکھتا ہے۔ آپ کے ISP، public instance کے operator اور خود engines کے سامنے اس کا کیا مطلب ہے، اس کی وضاحت SearXNG اصل میں کیا چھپاتا ہے میں کی گئی ہے۔

JSON request پر 403 Forbidden کیوں آتا ہے؟

اس کی 2 وجوہات ہیں، اور دونوں configuration سے متعلق ہیں۔ یا تو json، settings.yml میں search: کے تحت موجود formats فہرست میں شامل نہیں، جو default state ہے، یا limiter فعال ہے اور اس نے آپ کے script کو bot قرار دیا ہے۔ پہلے format شامل کریں، docker compose restart core کے ساتھ restart کریں، پھر دوبارہ کوشش کریں۔ اگر پھر بھی ناکام ہو تو limiter: false مقرر کریں اور access کو reverse proxy پر control کریں۔

اگر میں limiter بند رکھوں تو کیا Valkey container ضروری ہے؟

اسے running رہنے دیں۔ SearXNG اس کے بغیر کام کرتا ہے، لیکن اس کے بغیر limiter کو بعد میں فعال نہیں کیا جا سکتا، اور یہ دوسری مختصر مدت والی state بھی محفوظ رکھتا ہے۔ container چھوٹا ہے اور صرف cached data محفوظ کرتا ہے، اس لیے اسے ہٹانے سے بہت کم بچت ہوتی ہے اور آپ بعد میں اسے فعال کرنے کا اختیار کھو دیتے ہیں۔

SearXNG کو کیسے update کروں؟

/opt/searxng میں پہلے docker compose pull، پھر docker compose up -d چلائیں۔ Compose جس container کی image تبدیل ہوئی ہو اسے دوبارہ بناتا ہے اور آپ کی core-config/ directory کو برقرار رکھتا ہے، اس لیے settings.yml محفوظ رہتا ہے۔ چونکہ use_default_settings: true آپ کی keys کو shipped defaults پر merge کرتا ہے، اس لیے upstream میں شامل کیے گئے options file کو خراب کرنے کے بجائے مناسب values کے ساتھ دستیاب ہو جاتے ہیں۔

کیا کئی لوگ ایک instance شیئر کر سکتے ہیں؟

ہاں، اور یہی وہ صورت ہے جس میں آپ limiter فعال کرتے ہیں اور public_instance: true مقرر کرتے ہیں۔ Preferences ہر visitor کے اپنے browser میں محفوظ ہوتی ہیں، اس لیے accounts manage کرنے کی ضرورت نہیں ہوتی۔ instance public کرنے کے بعد ایک ہفتے تک /stats monitor کریں، کیونکہ upstream engines آپ کے server سے results غائب ہونے کا آپ کو علم ہونے سے بہت پہلے requests مسترد کرنا شروع کر دیتے ہیں۔