SSD Nodes Learn Hosting plans →
गाइड Matt Connorलेखक: Matt Connor

SearXNG को Docker Compose के साथ कैसे होस्ट करें

Docker Compose का उपयोग करके अपने VPS पर SearXNG को सेटअप करें। इस गाइड में settings.yml कॉन्फ़िगरेशन, Nginx TLS सुरक्षा और अपनी स्क्रिप्ट के लिए JSON API का उपयोग करना शामिल है।

आप क्या बना रहे हैं

SearXNG को self-host करने से आपको अपना निजी सर्च इंजन मिलता है जो आपके अपने सर्वर पर चलता है। SearXNG एक मेटासर्च इंजन है: यह आपकी क्वेरी लेता है, Google, Bing, DuckDuckGo और Wikipedia जैसे अन्य इंजनों से पूछता है, और फिर जो परिणाम आते हैं उन्हें एक पेज पर मिला देता है। कोई प्रोफाइल नहीं बनाई जाती और कोई ट्रैकिंग कुकी सेट नहीं की जाती, क्योंकि आपकी क्वेरी रखने वाली एकमात्र मशीन आपकी अपनी है। यदि आपको केवल Searx कहे जाने वाले पुराने गाइड मिले हैं, तो यह वही प्रोजेक्ट है जिससे यह fork हुआ है। यह सितंबर 2023 से unmaintained है, जब इसकी अपनी रिपॉजिटरी ने घोषणा की कि Searx का रखरखाव अब नहीं किया जा रहा है, और उसके बाद से हुआ एक commit, जो मई 2026 का एक डॉक्यूमेंटेशन नोट है, उसे नहीं बदलता है। इसलिए किसी एक का पालन करने से पहले दोनों की स्थिति की जाँच करें।

इसका स्टैक छोटा है। दो कंटेनर, एक सेटिंग्स फाइल, एक रिवर्स प्रॉक्सी। यह एक छोटे VPS पर आसानी से चल जाएगा, जो हर self-hosted सर्विस के बारे में सच नहीं है: PhotoPrism बनाम Immich में तौली गई फोटो लाइब्रेरी ने अपना RAM का न्यूनतम स्तर वेब ऐप के बजाय इंडेक्सर द्वारा निर्धारित किया था। वास्तविक निर्णय यह है कि क्या इंस्टेंस निजी है, जिसका अर्थ है कि केवल आप और आपकी अपनी स्क्रिप्ट उस तक पहुँचती हैं, या सार्वजनिक है, जिसका अर्थ है कि इंटरनेट पर कोई भी इसे क्वेरी कर सकता है। वह विकल्प सुरक्षा सेटिंग्स को बदल देता है, इसलिए कुछ भी टाइप करने से पहले उसे तय कर लें। डिफ़ॉल्ट उत्तर निजी है।

इसे चलाने का एक दूसरा कारण भी है। एक SearXNG इंस्टेंस JSON में बात करता है, इसलिए आपके द्वारा लिखी गई कोई भी स्क्रिप्ट या AI एजेंट को एक सर्च API मिलता है जिसका आप स्वामित्व रखते हैं, जिसमें कोई key नहीं, कोई प्रति-क्वेरी बिलिंग नहीं और कोई कोटा मेल नहीं होता है।

Docker Compose के साथ SearXNG इंस्टॉल करें

यह प्रोजेक्ट एक container image और एक Compose file प्रकाशित करता है। इन दोनों को एक नए Ubuntu 24.04 सर्वर पर pull करें, जिस पर 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 के लिए किया जाता है। यह container के अंदर /etc/searxng/ पर ./core-config/ को mount करता है, इसलिए आप जो कुछ भी configure करते हैं, वह host पर उसी एक directory में रहता है।

अब .env को edit करें। दिए गए उदाहरण में हर line comment की गई है, यही कारण है कि container हर address पर port 8080 पर start होता है। comment हटाएँ और इन तीन को set करें।

SEARXNG_VERSION=latest
SEARXNG_HOST=127.0.0.1
SEARXNG_PORT=8080

SEARXNG_HOST=127.0.0.1 सबसे महत्वपूर्ण है। यह published port को bare 8080:8080 के बजाय 127.0.0.1:8080:8080 बना देता है, जिसे Docker हर address पर publish करता है, ताकि container केवल loopback address पर ही response दे और internet उस तक सीधे न पहुँच सके। यदि आप इसे छोड़ देते हैं, तो container start होते ही expose हो जाता है, क्योंकि published Docker port आपके firewall rules से पहले insert हो जाता है। यह trap पूरी तरह पढ़ने लायक है: published Docker ports ufw को bypass करते हैं।

सीखते समय SEARXNG_VERSION=latest ठीक है। जिस सर्वर की आपको परवाह है, उस पर tag को pin करें। October 2026 तक release tags date पर आधारित हैं और 2026.10.4-d48c4b555 जैसे दिखते हैं, इसलिए एक pinned deployment तब upgrade होता है जब आप निर्णय लेते हैं, न कि तब जब registry आपके पीछे बदल जाती है। यही अनुशासन box पर किसी भी अन्य long-lived service के लिए भी फायदेमंद है, यही कारण है कि एक self-hosted RustDesk relay भी अपने image tags को pin करता है: remote access service का unattended upgrade सबसे खराब समय पर खुद को announce कर सकता है।

settings.yml: महत्वपूर्ण हिस्से

पहली बार start करने से पहले core-config/settings.yml बनाएँ। use_default_settings: true SearXNG को उसके अपने shipped defaults लोड करने और फिर केवल आपके द्वारा लिखे गए keys को लागू करने का निर्देश देता है, जिससे आपकी फाइल छोटी रहती है और नए options जोड़ने वाले upgrades के बाद भी सुरक्षित रहती है।

सबसे पहले secret generate करें, क्योंकि यह मान सीधे फाइल में जाता है।

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 डेटा को sign करता है। shipped default मान literal string ultrasecretkey है, और इसे ऐसे ही छोड़ने का मतलब है कि कोई भी जो इस default को जानता है, वह उन tokens को forge कर सकता है। इसे एक बार बदलें, फिर इसे न छुएं: इसे बाद में बदलने से सभी saved preferences हट जाते हैं।

base_url को trailing slash के साथ public HTTPS address होना चाहिए। यही वह पता है जिसे SearXNG अपने द्वारा render किए गए links में लिखता है। यदि इसे localhost पर छोड़ दिया जाए, तो remote browser में "next page" link पाठक की अपनी machine पर point करेगा और fail हो जाएगा।

formats यह तय करता है कि web endpoint किस प्रकार के output तैयार करेगा। json default list में नहीं है, इसलिए जब तक आप इसे जोड़ नहीं देते, JSON request 403 error देगी। image_proxy: true result thumbnails को आपके सर्वर के माध्यम से route करता है, ताकि उन images को host करने वाली sites कभी भी आपके visitors के addresses न देख सकें।

valkey.url hostname valkey का उपयोग करता है क्योंकि Compose file में यही service का नाम है, और Compose दोनों containers को एक ही network पर रखता है जहाँ service names resolve हो जाते हैं। इसे localhost पर point करें तो limiter fail हो जाता है, क्योंकि core container के अंदर localhost वही container होता है।

secret एक plain file में रहता है, इसलिए इसके आसपास की directory को भी सुरक्षित रखें। chmod 750 /opt/searxng अन्य host users को बाहर रखता है। आप core-config/settings.yml को बिना किसी समस्या के mode 600 तक सीमित कर सकते हैं: official container का entrypoint root के रूप में start होता है और, FORCE_OWNERSHIP को इसके default true पर छोड़ने पर, SearXNG के start होने से पहले mounted config directory को container के अपने searxng user को सौंप देता है, इसलिए फाइल उसके लिए readable बनी रहती है। इसका side effect host पर दिखता है: वही step core-config/ के owner को container के user ID में बदल देता है, इसलिए बाद में sudo के साथ फाइल edit करने की अपेक्षा रखें।

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 number के साथ parse error के रूप में दिखाई देती है।

इसे Nginx के पीछे TLS के साथ रखें

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

nginx -t reload करने से पहले syntax is ok और test is successful को print करता है। Certbot उसी file को rewrite करके certificate के साथ 443 पर listen करने के लिए सेट करता है और port 80 से redirect जोड़ता है। search.example.com के लिए DNS record पहले से ही इस server पर point करना चाहिए, क्योंकि certificate authority HTTP के माध्यम से file fetch करके ownership की पुष्टि करती है। renewal सहित पूरी प्रक्रिया Ubuntu 24.04 के लिए Certbot और Nginx गाइड में दी गई है।

ये दो forwarding headers केवल सजावट नहीं हैं। X-Forwarded-For और X-Real-IP के बिना, SearXNG पर आने वाली हर request में proxy का address होता है। इस कारण rate limiter को लगता है कि सारा traffic एक ही client से आ रहा है और वह visitors के बीच अंतर नहीं कर पाता।

स्क्रिप्ट और एजेंटों को JSON सर्च API की आवश्यकता क्यों होती है

json के साथ formats में, वही endpoint जो पेज को रेंडर करता है, स्ट्रक्चर्ड डेटा भी प्रदान करता है।

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

आपको एक ऑब्जेक्ट मिलता है जिसमें results ऐरे होता है, जहाँ प्रत्येक प्रविष्टि में url, title, content और उसे प्रदान करने वाला इंजन होता है, साथ ही answers, infoboxes और suggestions भी होते हैं। यह किसी समराइज़र, लिंक चेकर या रिसर्च लूप को फीड करने के लिए पर्याप्त है। उन परिणामों को किसी लैंग्वेज मॉडल को सौंपना दिखने में जितना सरल है, उससे कहीं बड़ा कदम है, क्योंकि सर्च परिणाम अविश्वसनीय टेक्स्ट होते हैं जिनमें स्वयं के निर्देश हो सकते हैं, और यही वह विषय है जिसे अपने SearXNG इंस्टेंस पर AI एजेंट को पॉइंट करना विस्तार से समझाता है।

यह एजेंट-आधारित किसी भी चीज़ के लिए महत्वपूर्ण है। एक लैंग्वेज मॉडल की ट्रेनिंग कटऑफ होती है, इसलिए वर्तमान के बारे में सवालों के जवाब देने के लिए उसे लाइव सर्च की आवश्यकता होती है, और कमर्शियल सर्च API प्रति क्वेरी शुल्क लेते हैं और उन पर सख्त रेट लिमिट होती है। एक लोकल इंस्टेंस की लागत आपके द्वारा पहले से भुगतान किए जा रहे सर्वर पर केवल एक कंटेनर की होती है, और क्वेरीज़ कभी भी उससे बाहर नहीं जातीं। यदि आप किसी मॉडल में टूल्स जोड़ रहे हैं, तो यही तर्क VPS पर MCP सर्वर चलाना के लिए भी लागू होता है, जहाँ सर्च टूल आमतौर पर पहला टूल होता है जिसे लोग जोड़ते हैं।

API उपयोग के लिए दो नियम हैं। इंस्टेंस को प्राइवेट रखें, इसलिए API साइड को लूपबैक एड्रेस या प्राइवेट नेटवर्क से बाइंड करें और केवल अपने होस्ट्स को ही इसे एक्सेस करने दें, ठीक वैसे ही जैसे एक सेल्फ-होस्टेड लोकेशन ट्रैकर को उस endpoint के लिए आवश्यकता होती है जहाँ आपका फोन अपनी स्थिति रिपोर्ट करता है। फिर इसे सावधानी से क्वेरी करें। SearXNG आपके अनुरोध को वास्तविक सर्च इंजनों को फॉरवर्ड करता है, इसलिए प्रति सेकंड सौ क्वेरी चलाने वाली स्क्रिप्ट Google से आपके सर्वर को ब्लॉक करने का अनुरोध कर रही होती है।

Limiter और एक public instance के लिए बदलाव

Limiter, SearXNG का bot defence है। यह request headers, addresses और request rates की निगरानी करता है और automated दिखने वाले traffic को drop कर देता है। इस 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 को ही अनुमति दे। यदि आपको किसी ऐसे laptop से private instance तक पहुँचना है जो अलग-अलग networks के बीच चलता रहता है, तो इसके सामने v3 onion address लगाना एक चौथा विकल्प है, क्योंकि tor इंटरनेट पर कुछ भी नया expose किए बिना उसी loopback port से connect हो जाता है।

यदि आप instance को अन्य लोगों के लिए publish करते हैं, तो दोनों switches को on कर दें।

server:
  limiter: true
  public_instance: true

अधिक सूक्ष्म नियंत्रण core-config/limiter.toml में होता है, जिसे container /etc/searxng/limiter.toml पर read करता है। आप केवल उन्हीं keys को लिखें जिन्हें आप बदलना चाहते हैं। Proxy के पीछे आपको proxy घोषित करना होगा, अन्यथा 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 करने योग्य चीजों की अधिकांश संक्षिप्त सूचियों में शामिल है। उन सूचियों में हर entry infrastructure नहीं होती: Jellyfin library को 90 के दशक के rental store जैसा बनाना उसी nginx block के पीछे वही एक container है, जो workflow के बजाय फुर्सत के समय के लिए है।

खोज परिणाम खाली क्यों आते हैं

अपने instance पर /stats खोलें। यह प्रत्येक engine को उसकी error rate और response time के साथ सूचीबद्ध करता है, और जब परिणाम कम महसूस हों तो सबसे पहले यहीं देखना चाहिए।

"Access denied" या "CAPTCHA" त्रुटियों के साथ दिखने वाला engine आपके server address को ब्लॉक कर चुका है। data centre ranges में मौजूद addresses के लिए यह सामान्य है, क्योंकि search engines यह मान लेते हैं कि वे scrapers के हैं। SearXNG फिर विफल engine को retry करने के बजाय कुछ समय के लिए निलंबित कर देता है, इसलिए एक ब्लॉक हुआ engine चुपचाप आपके परिणामों से बाहर हो जाता है। इसे settings.yml में disable करें या इस नुकसान को स्वीकार करें। केवल यही दो विकल्प नहीं हैं, क्योंकि कुछ CAPTCHA blocks का समाधान ऐसा है जो restart के बाद भी बना रहता है। शेष engines अभी भी उत्तर देते हैं। 429 एक अस्पष्ट स्थिति है, क्योंकि यह आपके स्वयं के limiter से या किसी upstream engine द्वारा आपके server को मना करने से आ सकती है, और log line आपको बताती है कि आप इनमें से किसका सामना कर रहे हैं इससे पहले कि आप settings बदलना शुरू करें।

यदि सभी engines एक साथ विफल हो जाते हैं, तो container के पास कोई कार्यशील outbound name resolution नहीं है या internet तक कोई route नहीं है। container के अंदर से इसकी जाँच करें।

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

box पर कोई भी चीज़ आपको यह नहीं बताएगी कि वह जाँच कब विफल होने लगती है, इसलिए इसे cron से चलाएँ और विफलता को अपने स्वयं के ntfy server से अपने फोन पर alert भेजने दें बजाय इसके कि आप तब तक प्रतीक्षा करें जब तक आप यह न देख लें कि परिणाम कम हो गए हैं।

FAQ

क्या SearXNG मेरी खोजों को गुमनाम बनाता है?

यह उन सर्च इंजनों से आपकी पहचान छिपाता है जिन्हें यह क्वेरी भेजता है, क्योंकि वे आपके ब्राउज़र के बजाय आपके सर्वर को अनुरोध करते हुए देखते हैं। यह आपके सर्वर से क्वेरी को नहीं छिपाता है, और यह आपके सर्वर को उन सर्च इंजनों से नहीं छिपाता है। एक सिंगल-यूज़र इंस्टेंस पर उस पते से आने वाला सारा ट्रैफ़िक आपका होता है, इसलिए वह पता ही आपकी पहचान बन जाता है। आपके ब्राउज़र और आपके इंस्टेंस के बीच का ट्रैफ़िक TLS certificate द्वारा सुरक्षित रहता है। आपके ISP, पब्लिक इंस्टेंस के ऑपरेटर और सर्च इंजनों के सामने आपकी स्थिति क्या है, इसे SearXNG वास्तव में क्या छिपाता है में विस्तार से समझाया गया है।

JSON अनुरोध 403 Forbidden क्यों देता है?

इसके दो कारण हैं, और दोनों कॉन्फ़िगरेशन से संबंधित हैं। या तो json, settings.yml में search: के अंतर्गत formats सूची से गायब है, जो कि डिफ़ॉल्ट स्थिति है, या फिर लिमिटर चालू है और उसने आपकी स्क्रिप्ट को बॉट के रूप में वर्गीकृत कर दिया है। पहले फॉर्मेट जोड़ें, docker compose restart core के साथ रीस्टार्ट करें, और फिर पुनः प्रयास करें। यदि यह अभी भी विफल रहता है, तो limiter: false सेट करें और रिवर्स प्रॉक्सी पर एक्सेस को नियंत्रित करें।

यदि मैं लिमिटर बंद रखूँ तो क्या मुझे Valkey कंटेनर की आवश्यकता है?

इसे चलते रहने दें। SearXNG इसके बिना काम करता है, लेकिन इसके बिना बाद में लिमिटर को चालू नहीं किया जा सकता है, और यह अन्य अल्पकालिक स्टेट (short-lived state) को भी सुरक्षित रखता है। कंटेनर छोटा है और केवल कैश किया गया डेटा स्टोर करता है, इसलिए इसे हटाने से बहुत कम बचत होती है और आप एक विकल्प खो देते हैं।

मैं SearXNG को अपडेट कैसे करूँ?

/opt/searxng में पहले docker compose pull और फिर docker compose up -d चलाएँ। Compose किसी भी ऐसे कंटेनर को फिर से बनाता है जिसकी इमेज बदल गई है और आपकी core-config/ डायरेक्टरी को सुरक्षित रखता है, इसलिए settings.yml बना रहता है। चूँकि use_default_settings: true आपकी कुंजियों को डिफ़ॉल्ट सेटिंग्स के साथ मर्ज करता है, इसलिए अपस्ट्रीम द्वारा जोड़े गए विकल्प फ़ाइल को खराब करने के बजाय उचित मानों के साथ आते हैं।

क्या कई लोग एक ही इंस्टेंस साझा कर सकते हैं?

हाँ, और यही वह स्थिति है जहाँ आप लिमिटर को चालू करते हैं और public_instance: true सेट करते हैं। प्राथमिकताएँ प्रत्येक विज़िटर के अपने ब्राउज़र में संग्रहीत होती हैं, इसलिए प्रबंधित करने के लिए कोई अकाउंट नहीं होता है। इसे खोलने के बाद एक सप्ताह तक /stats पर नज़र रखें, क्योंकि परिणाम गायब होने का पता चलने से बहुत पहले ही अपस्ट्रीम इंजन आपके सर्वर को रिजेक्ट करना शुरू कर सकते हैं।

क्या यह लेख उपयोगी था?