SearXNG को Docker Compose के साथ कैसे होस्ट करें
अपने VPS पर SearXNG को Docker Compose के साथ सेटअप करें। इसमें settings.yml कॉन्फ़िगरेशन, Nginx TLS सुरक्षा और अपनी स्क्रिप्ट के लिए निजी JSON सर्च API बनाने का तरीका शामिल है।
आप क्या बना रहे हैं
SearXNG को स्वयं होस्ट करने का अर्थ है एक निजी सर्च इंजन का उपयोग करना जो आपके अपने सर्वर पर चलता है। SearXNG एक मेटासर्च इंजन है: यह आपकी क्वेरी लेता है, Google, Bing, DuckDuckGo और Wikipedia जैसे अन्य इंजनों से पूछता है, और फिर प्राप्त परिणामों को एक पेज पर जोड़ देता है। कोई प्रोफाइल नहीं बनाई जाती है और कोई ट्रैकिंग कुकी सेट नहीं की जाती है, क्योंकि आपकी क्वेरी को रखने वाली एकमात्र मशीन आपकी अपनी है।
इसका स्टैक छोटा है। दो कंटेनर, एक सेटिंग्स फ़ाइल, और एक रिवर्स प्रॉक्सी। मुख्य निर्णय यह है कि क्या इंस्टेंस निजी है, जिसका अर्थ है कि केवल आप और आपकी अपनी स्क्रिप्ट्स ही इसे एक्सेस कर सकती हैं, या सार्वजनिक है, जिसका अर्थ है कि इंटरनेट पर कोई भी इसे क्वेरी कर सकता है। यह विकल्प सुरक्षा सेटिंग्स को बदल देता है, इसलिए कुछ भी टाइप करने से पहले इसे तय कर लें। डिफ़ॉल्ट विकल्प निजी है।
इसे चलाने का दूसरा कारण भी है। एक SearXNG इंस्टेंस JSON का उपयोग करता है, इसलिए आपके द्वारा लिखी गई कोई भी स्क्रिप्ट या AI एजेंट को एक ऐसा सर्च API मिलता है जो आपका अपना है, जिसमें कोई की (key) नहीं है, प्रति-क्वेरी कोई बिलिंग नहीं है और कोई कोटा ईमेल नहीं है।
Docker Compose के साथ SearXNG इंस्टॉल करें
यह प्रोजेक्ट एक कंटेनर इमेज और एक Compose फ़ाइल प्रकाशित करता है। इन दोनों को एक नए Ubuntu 24.04 सर्वर पर पुल करें, जिसमें Docker Engine और Compose प्लगइन पहले से मौजूद हों। यदि आप 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 .envCompose फ़ाइल दो सेवाओं को परिभाषित करती है। core स्वयं SearXNG है, और valkey एक इन-मेमोरी डेटा स्टोर है जिसका उपयोग रेट लिमिटिंग और अल्पकालिक स्टेट के लिए किया जाता है। यह कंटेनर के अंदर /etc/searxng/ पर ./core-config/ को माउंट करता है, इसलिए आपके द्वारा कॉन्फ़िगर की गई हर चीज़ होस्ट पर उसी एक डायरेक्टरी में रहती है।
अब .env को एडिट करें। दिए गए उदाहरण में प्रत्येक लाइन को कमेंट आउट किया गया है, यही कारण है कि कंटेनर हर एड्रेस पर पोर्ट 8080 पर शुरू होता है। इन तीनों को अनकमेंट करें और सेट करें।
SEARXNG_VERSION=latest
SEARXNG_HOST=127.0.0.1
SEARXNG_PORT=8080SEARXNG_HOST=127.0.0.1 महत्वपूर्ण है। यह पब्लिश किए गए पोर्ट को [::]:8080:8080 के बजाय 127.0.0.1:8080:8080 बनाता है, ताकि कंटेनर केवल लूपबैक एड्रेस पर ही उत्तर दे और इंटरनेट सीधे उस तक न पहुँच सके। इसे छोड़ देने पर कंटेनर शुरू होते ही एक्सपोज़ हो जाता है, क्योंकि पब्लिश किया गया Docker पोर्ट आपके फ़ायरवॉल नियमों से पहले इंसर्ट हो जाता है। यह चेतावनी पूरी तरह पढ़ने योग्य है: पब्लिश किए गए Docker पोर्ट ufw को बायपास करते हैं।
सीखने के दौरान SEARXNG_VERSION=latest ठीक है। जिस सर्वर की आपको परवाह है, उस पर टैग को पिन करें। जुलाई 2026 तक रिलीज़ टैग तारीख पर आधारित हैं और 2026.3.25-541c6c3cb जैसे दिखते हैं, इसलिए एक पिन किया गया डिप्लॉयमेंट तब अपग्रेड होता है जब आप निर्णय लेते हैं, न कि तब जब रजिस्ट्री आपके पीछे बदल जाती है।
settings.yml: महत्वपूर्ण भाग
पहली बार शुरू करने से पहले core-config/settings.yml बनाएं। use_default_settings: true SearXNG को अपने डिफ़ॉल्ट मान लोड करने और फिर केवल आपके द्वारा लिखी गई कुंजियों को लागू करने का निर्देश देता है, जिससे आपकी फ़ाइल संक्षिप्त रहती है और नए विकल्पों को जोड़ने वाले अपग्रेड के बाद भी सुरक्षित रहती है।
सबसे पहले secret जनरेट करें, क्योंकि इसका मान सीधे फ़ाइल में जाता है।
openssl rand -hex 32use_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
- jsonsecret_key सत्र और टोकन डेटा को साइन करता है। शिप किया गया डिफ़ॉल्ट मान शाब्दिक स्ट्रिंग ultrasecretkey है, और इसे ऐसे ही छोड़ने का अर्थ है कि जो कोई भी इस डिफ़ॉल्ट को जानता है वह उन टोकन को बना सकता है। इसे एक बार बदलें, फिर इसे न बदलें: इसे बाद में बदलने से सभी सहेजी गई प्राथमिकताएं हट जाएंगी।
base_url को ट्रेलिंग स्लैश के साथ सार्वजनिक HTTPS पता होना चाहिए। यह वही है जिसे SearXNG अपने द्वारा रेंडर किए गए लिंक में लिखता है। इसे localhost पर इंगित करने पर रिमोट ब्राउज़र में "अगला पृष्ठ" लिंक पाठक की अपनी मशीन पर इंगित करेगा और विफल हो जाएगा।
formats यह तय करता है कि वेब एंडपॉइंट किस प्रकार के आउटपुट तैयार करेगा। json डिफ़ॉल्ट सूची में नहीं है, इसलिए जब तक आप इसे नहीं जोड़ते, तब तक JSON अनुरोध 403 त्रुटि लौटाएगा। image_proxy: true परिणाम थंबनेल को आपके सर्वर के माध्यम से रूट करता है, ताकि उन छवियों को होस्ट करने वाली साइटें आपके आगंतुकों के पते कभी न देख सकें।
valkey.url होस्टनाम valkey का उपयोग करता है क्योंकि यह Compose फ़ाइल में सेवा का नाम है, और Compose दोनों कंटेनरों को एक नेटवर्क पर रखता है जहाँ सेवा नाम रिज़ॉल्व होते हैं। इसे localhost पर इंगित करें और लिमिटर विफल हो जाएगा, क्योंकि core कंटेनर के अंदर localhost वही कंटेनर होता है।
secret एक सादी फ़ाइल में होता है, इसलिए फ़ाइल के बजाय उसके आसपास की निर्देशिका को सुरक्षित रखें। chmod 750 /opt/searxng अन्य होस्ट उपयोगकर्ताओं को बाहर रखता है। core-config/settings.yml को मोड 600 तक सीमित न करें: कंटेनर अपने स्वयं के अनप्रिविलेज्ड उपयोगकर्ता के रूप में चलता है, और यदि वह फ़ाइल को पढ़ नहीं सकता है, तो SearXNG शुरू ही नहीं होगा।
स्टैक शुरू करें और इसकी जांच करें।
cd /opt/searxng
docker compose up -d
docker compose ps
curl -I http://127.0.0.1:8080/docker compose ps को दोनों कंटेनरों को running स्थिति में दिखाना चाहिए। curl को HTTP/1.1 200 OK उत्तर देना चाहिए। यदि यह कोई उत्तर नहीं देता है, तो docker compose logs core पढ़ें, क्योंकि settings.yml में YAML की गलती वहां एक पार्स त्रुटि के रूप में दिखाई देती है जो लाइन का नाम बताती है।
इसे nginx के पीछे TLS के साथ रखें
कंटेनर केवल loopback पर सुनता है, इसलिए 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.comnginx -t, reload करने से पहले syntax is ok और test is successful प्रिंट करता है। Certbot उसी फ़ाइल को फिर से लिखता है ताकि वह 443 पर सर्टिफिकेट के साथ सुन सके और पोर्ट 80 से एक रीडायरेक्ट जोड़ सके। search.example.com के लिए DNS रिकॉर्ड पहले से ही इस सर्वर पर पॉइंट करना चाहिए, क्योंकि सर्टिफिकेट अथॉरिटी HTTP के माध्यम से एक फ़ाइल प्राप्त करके स्वामित्व की पुष्टि करती है। नवीनीकरण (renewal) सहित पूरी प्रक्रिया Ubuntu 24.04 के लिए Certbot और nginx गाइड में दी गई है।
दो फॉरवर्डिंग हेडर केवल सजावट नहीं हैं। X-Forwarded-For और X-Real-IP के बिना, SearXNG पर आने वाला प्रत्येक अनुरोध प्रॉक्सी एड्रेस ले जाता है, इसलिए रेट लिमिटर को लगता है कि एक ही क्लाइंट सारा ट्रैफ़िक भेज रहा है और वह आगंतुकों के बीच अंतर नहीं कर पाता है।
स्क्रिप्ट और एजेंटों को JSON सर्च API की आवश्यकता क्यों है
json के साथ formats में, वही एंडपॉइंट जो पेज को रेंडर करता है, स्ट्रक्चर्ड डेटा भी लौटाता है।
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 भी होते हैं। यह किसी समराइज़र, लिंक चेकर, या रिसर्च लूप को फीड करने के लिए पर्याप्त है।
यह एजेंट के आकार की किसी भी चीज़ के लिए मायने रखता है। एक लैंग्वेज मॉडल का ट्रेनिंग कटऑफ होता है, इसलिए उसे वर्तमान के बारे में सवालों के जवाब देने के लिए लाइव सर्च की आवश्यकता होती है, और कमर्शियल सर्च API प्रति क्वेरी शुल्क लेते हैं और रेट लिमिट को सख्ती से लागू करते हैं। एक लोकल इंस्टेंस का खर्च उस सर्वर पर केवल एक कंटेनर का होता है जिसके लिए आप पहले से भुगतान कर रहे हैं, और क्वेरी कभी भी उससे बाहर नहीं जाती हैं। यदि आप किसी मॉडल में टूल्स जोड़ रहे हैं, तो यही तर्क VPS पर MCP सर्वर चलाने को प्रेरित करता है, जहाँ सर्च टूल आमतौर पर वह पहला टूल होता है जिसे लोग जोड़ते हैं।
API उपयोग के लिए दो नियम हैं। इंस्टेंस को प्राइवेट रखें, इसलिए API साइड को लूपबैक एड्रेस या प्राइवेट नेटवर्क से बाइंड करें और केवल अपने होस्ट्स को ही इसे एक्सेस करने दें। फिर इसे सावधानी से क्वेरी करें। SearXNG आपके अनुरोध को वास्तविक सर्च इंजनों को फॉरवर्ड करता है, इसलिए प्रति सेकंड सौ क्वेरी चलाने वाली स्क्रिप्ट Google से आपके सर्वर को ब्लॉक करने के लिए कह रही है।
लिमिटर, और एक पब्लिक इंस्टेंस के लिए क्या बदलता है
लिमिटर SearXNG का बॉट डिफेंस है। यह रिक्वेस्ट हेडर, एड्रेस और रिक्वेस्ट रेट की निगरानी करता है, और जो ट्रैफिक ऑटोमेटेड दिखता है उसे ड्रॉप कर देता है। इस स्थिति को बनाए रखने के लिए इसे Valkey की आवश्यकता होती है, इसीलिए Compose फाइल इसे साथ में देती है।
एक प्राइवेट इंस्टेंस पर limiter: false को चालू रखें। आपकी अपनी स्क्रिप्ट्स परिभाषा के अनुसार ऑटोमेटेड ट्रैफिक हैं, इसलिए लिमिटर ठीक उन्हीं JSON कॉल्स को ब्लॉक कर देगा जिनके लिए आपने इंस्टेंस बनाया है। एक्सेस कंट्रोल का काम रिवर्स प्रॉक्सी का है: nginx location में एक allow और deny पेयर, HTTP बेसिक ऑथेंटिकेशन, या एक फायरवॉल जो केवल आपके अन्य सर्वर्स को ही अनुमति देता है।
यदि आप इंस्टेंस को अन्य लोगों के लिए पब्लिश करते हैं, तो दोनों स्विच चालू कर दें।
server:
limiter: true
public_instance: trueबेहतर नियंत्रण core-config/limiter.toml में होता है, जिसे कंटेनर /etc/searxng/limiter.toml पर पढ़ता है। आप केवल उन्हीं कीज़ को लिखें जिन्हें आप बदलना चाहते हैं। प्रॉक्सी के पीछे आपको प्रॉक्सी को घोषित करना होगा, अन्यथा लिमिटर आपके nginx एड्रेस को ही एकमात्र अपमानजनक क्लाइंट मान लेगा।
[botdetection]
trusted_proxies = [
'127.0.0.0/8',
'::1',
]
[botdetection.ip_limit]
link_token = truelink_token = true SearXNG को एक टोकन जारी करने के लिए कहता है जिसे केवल एक वास्तविक ब्राउज़र सेशन ही फेच करेगा, जो अधिकांश साधारण स्क्रैपर्स को रोक देता है। उम्मीद रखें कि एक पब्लिक इंस्टेंस कुछ ही दिनों में उन्हें आकर्षित कर लेगा। इंजन एरर्स की भी उम्मीद रखें, क्योंकि आप जितना अधिक ट्रैफिक फॉरवर्ड करेंगे, अपस्ट्रीम इंजन उतनी ही जल्दी आपके सर्वर एड्रेस पर CAPTCHA भेजना शुरू कर देंगे। एक पब्लिक SearXNG इंस्टेंस एक निरंतर चलने वाला काम है। एक प्राइवेट इंस्टेंस ऐसा नहीं है, इसीलिए यह 2026 में सेल्फ-होस्ट करने योग्य चीजें की अधिकांश संक्षिप्त सूचियों में शामिल है।
खोज परिणाम खाली क्यों आते हैं
अपने इंस्टेंस पर /stats खोलें। यह प्रत्येक इंजन को उसकी त्रुटि दर और प्रतिक्रिया समय के साथ सूचीबद्ध करता है, और जब परिणाम कम महसूस हों तो यह सबसे पहले देखी जाने वाली जगह है।
"Access denied" या "CAPTCHA" त्रुटियों के साथ प्रदर्शित होने वाला इंजन आपके सर्वर पते को ब्लॉक कर चुका है। डेटा सेंटर रेंज वाले पतों के लिए यह सामान्य है, क्योंकि सर्च इंजन यह मान लेते हैं कि वे स्क्रैपर्स के हैं। SearXNG फिर विफल इंजन को पुनः प्रयास करने के बजाय कुछ समय के लिए निलंबित कर देता है, इसलिए एक ब्लॉक किया गया इंजन चुपचाप आपके परिणामों से बाहर हो जाता है। इसे settings.yml में अक्षम करें या नुकसान को स्वीकार करें। शेष इंजन अभी भी उत्तर देते हैं।
यदि सभी इंजन एक साथ विफल हो जाते हैं, तो कंटेनर में कोई कार्यशील आउटबाउंड नाम रिज़ॉल्यूशन नहीं है या इंटरनेट के लिए कोई रूट नहीं है। कंटेनर के अंदर से इसका परीक्षण करें।
docker compose exec core wget -qO- https://duckduckgo.com > /dev/null && echo okFAQ
क्या SearXNG मेरी खोजों को गुमनाम बनाता है?
यह उन सर्च इंजनों से आपकी पहचान छिपाता है जिनसे यह क्वेरी करता है, क्योंकि वे आपके ब्राउज़र के बजाय आपके सर्वर को अनुरोध करते हुए देखते हैं। यह आपके सर्वर से क्वेरी को नहीं छिपाता है, और यह आपके सर्वर को उनसे नहीं छिपाता है। एक एकल उपयोगकर्ता इंस्टेंस पर उस पते से आने वाला सारा ट्रैफ़िक आपका होता है, इसलिए पता स्वयं ही पहचानकर्ता बन जाता है। आपके ब्राउज़र और आपके इंस्टेंस के बीच का ट्रैफ़िक TLS सर्टिफिकेट द्वारा सुरक्षित होता है।
JSON अनुरोध 403 Forbidden क्यों लौटाता है?
इसके दो कारण हैं, और दोनों कॉन्फ़िगरेशन से संबंधित हैं। या तो json, settings.yml में search: के अंतर्गत formats सूची से गायब है, जो कि डिफ़ॉल्ट स्थिति है, या लिमिटर चालू है और उसने आपकी स्क्रिप्ट को बॉट के रूप में वर्गीकृत किया है। पहले फॉर्मेट जोड़ें, docker compose restart core के साथ रीस्टार्ट करें, फिर पुनः प्रयास करें। यदि यह अभी भी विफल रहता है, तो limiter: false सेट करें और रिवर्स प्रॉक्सी पर एक्सेस को नियंत्रित करें।
यदि मैं लिमिटर बंद रखता हूँ तो क्या मुझे Valkey कंटेनर की आवश्यकता है?
इसे चलते रहने दें। SearXNG इसके बिना काम करता है, लेकिन इसके बिना बाद में लिमिटर को चालू नहीं किया जा सकता है, और यह अन्य अल्पकालिक स्थिति (state) को भी रखता है। कंटेनर छोटा है और केवल कैश किया गया डेटा संग्रहीत करता है, इसलिए इसे हटाने से बहुत कम बचत होती है और आप एक विकल्प खो देते हैं।
मैं SearXNG को अपडेट कैसे करूँ?
/opt/searxng में पहले docker compose pull और फिर docker compose up -d चलाएँ। Compose किसी भी ऐसे कंटेनर को फिर से बनाता है जिसकी इमेज बदल गई है और आपकी core-config/ डायरेक्टरी को अछूता छोड़ देता है, इसलिए settings.yml सुरक्षित रहता है। चूँकि use_default_settings: true आपकी कुंजियों को शिप किए गए डिफ़ॉल्ट के साथ मर्ज करता है, इसलिए अपस्ट्रीम में जोड़े गए विकल्प फ़ाइल को तोड़ने के बजाय उचित मानों के साथ आते हैं।
क्या कई लोग एक इंस्टेंस साझा कर सकते हैं?
हाँ, और यही वह स्थिति है जहाँ आप लिमिटर को चालू करते हैं और public_instance: true सेट करते हैं। प्राथमिकताएँ प्रत्येक विज़िटर के अपने ब्राउज़र में संग्रहीत होती हैं, इसलिए प्रबंधित करने के लिए कोई अकाउंट नहीं होते हैं। इसे खोलने के बाद एक सप्ताह तक /stats पर नज़र रखें, क्योंकि आपके परिणाम गायब होने का पता चलने से बहुत पहले ही अपस्ट्रीम इंजन आपके सर्वर को अस्वीकार करना शुरू कर देते हैं।