SearXNG स्वतःच्या VPS वर कसे self-host करावे
Docker Compose वापरून स्वतःच्या VPS वर SearXNG चालवा: settings.yml, limiter, TLS सह nginx आणि scripts साठी वापरता येणारा JSON search API सेट करा.
तुम्ही काय तयार करत आहात
SearXNG self-host केल्यास तुमच्या स्वतःच्या सर्व्हरवर चालणारे खाजगी search engine मिळते. SearXNG हे metasearch engine आहे. ते तुमची query Google, Bing, DuckDuckGo आणि Wikipedia यांसारख्या इतर engines कडे पाठवते आणि परत आलेले परिणाम एका result page मध्ये एकत्र करते. कोणतेही profile तयार केले जात नाही आणि tracking cookie सेट केली जात नाही, कारण तुमची query जतन करणारे एकमेव machine तुमचे स्वतःचे असते. तुम्हाला फक्त Searx नावाच्या जुन्या प्रकल्पावरील guides सापडल्या असतील, तर हाच तो प्रकल्प आहे ज्यापासून SearXNG fork झाले. त्या प्रकल्पात 2023 नंतर कोणताही commit झालेला नाही. त्यामुळे एखाद्या मार्गदर्शकाचे अनुसरण करण्यापूर्वी दोन्ही प्रकल्पांची सद्यस्थिती तपासा.
हा stack लहान आहे. दोन containers, एक settings file आणि एक reverse proxy एवढेच आवश्यक आहे. तो छोट्या VPS वर सहज चालतो. मात्र प्रत्येक self-hosted service बाबत हे खरे नसते. PhotoPrism आणि Immich यांची तुलना करताना विचारात घेतलेल्या photo libraries साठी RAM ची किमान गरज web app पेक्षा indexer ठरवतो. खरी निवड instance private ठेवायचा की public ठेवायचा ही आहे. Private instance म्हणजे फक्त तुम्ही आणि तुमच्या स्वतःच्या scripts त्याच्यापर्यंत पोहोचतात. Public instance म्हणजे internet वरील कोणतीही व्यक्ती त्यावर query चालवू शकते. या निवडीमुळे security settings बदलतात. त्यामुळे काहीही type करण्यापूर्वी हा निर्णय घ्या. Default पर्याय private आहे.
Instance चालवण्याचे आणखी एक कारण आहे. SearXNG instance JSON मध्ये प्रतिसाद देते. त्यामुळे तुम्ही लिहिलेल्या कोणत्याही script किंवा AI agent ला तुमच्या मालकीचा search API मिळतो. त्यासाठी key, प्रत्येक query साठी billing किंवा quota संबंधी email आवश्यक नसतो.
Docker Compose सह SearXNG स्थापित करा
हा प्रकल्प container image आणि Compose file प्रकाशित करतो. Docker Engine आणि Compose plugin आधीपासून असलेल्या नवीन Ubuntu 24.04 server वर दोन्ही आणा. 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 file मध्ये दोन services परिभाषित आहेत. core हा SearXNG आहे आणि valkey हा rate limiting तसेच अल्पकालीन state साठी वापरला जाणारा in-memory data store आहे. तो ./core-config/ ला container मध्ये /etc/searxng/ येथे mount करतो. त्यामुळे तुम्ही configure केलेली सर्व माहिती host वरील त्या एकाच directory मध्ये राहते.
आता .env संपादित करा. वितरित केलेल्या example मधील प्रत्येक ओळ comment केलेली आहे. म्हणूनच container प्रत्येक address वर port 8080 वर सुरू होतो. या तीन ओळी uncomment करून त्यांची मूल्ये सेट करा.
SEARXNG_VERSION=latest
SEARXNG_HOST=127.0.0.1
SEARXNG_PORT=8080SEARXNG_HOST=127.0.0.1 सर्वात महत्त्वाचे आहे. यामुळे published port 127.0.0.1:8080:8080 होतो, [::]:8080:8080 नाही. त्यामुळे container फक्त loopback address वर उत्तर देतो आणि internet त्याच्यापर्यंत थेट पोहोचू शकत नाही. हे वगळल्यास container सुरू होताच बाहेरून उपलब्ध होतो, कारण published Docker port तुमच्या firewall rules च्या आधी लागू केला जातो. हा धोका सविस्तर समजून घेण्यासाठी published Docker ports हे ufw bypass करतात वाचा.
तुम्ही शिकत असताना SEARXNG_VERSION=latest योग्य आहे. महत्त्वाच्या server वर tag निश्चित करा. July 2026 पर्यंत release tags date आधारित असून 2026.3.25-541c6c3cb सारखे दिसतात. त्यामुळे registry मध्ये बदल झाल्यावर नव्हे, तर तुम्ही ठरवाल तेव्हा pinned deployment upgrade होते. Server वर दीर्घकाळ चालणाऱ्या इतर components साठीही हीच शिस्त उपयुक्त ठरते. म्हणूनच self-hosted RustDesk relay देखील image tags निश्चित करतो: remote access service चे unattended upgrade सर्वात अयोग्य वेळी लक्षात येते.
settings.yml: महत्त्वाचे भाग
पहिल्यांदा सुरू करण्यापूर्वी core-config/settings.yml तयार करा. use_default_settings: true SearXNG ला त्याच्यासोबत आलेली default settings लोड करून तुम्ही लिहिलेल्या keys तेवढ्याच लागू करण्यास सांगते. त्यामुळे तुमची file लहान राहते आणि नवीन options असलेल्या upgrades नंतरही कार्यरत राहते.
प्रथम secret तयार करा, कारण त्याची value थेट file मध्ये लिहिली जाईल.
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 session आणि token data वर स्वाक्षरी करते. सोबत दिलेली default value ही अक्षरशः ultrasecretkey आहे. ती तशीच ठेवल्यास हा default माहीत असलेली कोणतीही व्यक्ती ते tokens बनावट तयार करू शकते. ती एकदा बदला आणि नंतर तशीच ठेवा. नंतर ती बदलल्यास जतन केलेली प्रत्येक preference नष्ट होते.
base_url हा शेवटी slash असलेला सार्वजनिक HTTPS address असणे आवश्यक आहे. SearXNG तयार करत असलेल्या links मध्ये हा address लिहिला जातो. तो localhost कडे निर्देशित ठेवल्यास remote browser मधील "next page" link वाचकाच्या स्वतःच्या machine कडे निर्देशित होतो आणि अपयशी ठरतो.
formats web endpoint कोणते output types तयार करेल हे ठरवते. json default list मध्ये नाही. त्यामुळे ते add करेपर्यंत JSON request ला 403 मिळतो. image_proxy: true result thumbnails तुमच्या server मार्फत पाठवते. त्यामुळे ती images host करणाऱ्या sites ना तुमच्या visitors चे addresses दिसत नाहीत.
valkey.url मध्ये hostname म्हणून valkey वापरा, कारण Compose file मध्ये तो service name आहे. Compose दोन्ही containers ना एकाच network वर ठेवते आणि त्या network वर service names resolve होतात. त्याऐवजी localhost कडे निर्देश केल्यास limiter अपयशी ठरतो, कारण core container मध्ये localhost म्हणजे तोच container असतो.
secret plain file मध्ये ठेवलेला आहे. त्यामुळे file पेक्षा तिच्या भोवतालच्या directory चे संरक्षण करा. chmod 750 /opt/searxng इतर host users ना बाहेर ठेवते. core-config/settings.yml ला mode 600 करण्याइतके permissions कडक करू नका. Container स्वतःच्या unprivileged user म्हणून चालतो. त्या user ला file वाचता आली नाही, तर SearXNG सुरूच होत नाही.
Stack सुरू करून तपासा.
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 म्हणून दिसते.
nginx आणि TLS मागे ठेवा
कंटेनर फक्त loopback वर ऐकतो. त्यामुळे तो पोहोचण्यायोग्य करण्यासाठी nginx आवश्यक आहे. Transport Layer Security (TLS) जोडण्याचे कामही nginx करते. /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.comReload करण्यापूर्वी nginx -t, syntax is ok आणि test is successful प्रदर्शित करते. Certbot त्याच फाइलमध्ये बदल करून प्रमाणपत्रासह 443 वर ऐकण्याची configuration तयार करते आणि port 80 वरून redirect जोडते. search.example.com साठीचा DNS record आधीच या server कडे निर्देशित असणे आवश्यक आहे, कारण प्रमाणपत्र प्राधिकरण HTTP द्वारे फाइल fetch करून मालकीची पडताळणी करते. Renewal सहित संपूर्ण मार्गदर्शक Ubuntu 24.04 साठीचे Certbot आणि nginx मार्गदर्शक येथे आहे.
ही दोन forwarding headers केवळ सजावटीसाठी नाहीत. X-Forwarded-For आणि X-Real-IP नसतील, तर SearXNG कडे येणाऱ्या प्रत्येक request मध्ये proxy address दिसतो. त्यामुळे rate limiter ला सर्व traffic करणारा एकच client दिसतो आणि वेगवेगळ्या visitors मध्ये फरक करता येत नाही.
स्क्रिप्ट्स आणि agents ना JSON search API का हवी असते
json सह formats मध्ये, page render करणारा तोच endpoint structured data परत करतो.
curl -s 'http://127.0.0.1:8080/search?q=wireguard+mtu&format=json' \
| jq -r '.results[0:5][] | .url'तुम्हाला url, title, content आणि तो data पुरवणारे engine असलेला results array मिळतो. त्यासोबत answers, infoboxes आणि suggestions देखील मिळतात. Summariser, link checker किंवा research loop ला data देण्यासाठी एवढे पुरेसे आहे. हे results language model कडे देणे दिसते त्यापेक्षा मोठे पाऊल आहे. Search results हा अविश्वसनीय text असतो आणि त्यात स्वतःच्या instructions असू शकतात. AI agent ला तुमच्या SearXNG instance कडे निर्देशित करणे याच विषयाचा सविस्तर विचार करते.
Agent स्वरूपाच्या कोणत्याही कामासाठी हे महत्त्वाचे आहे. Language model ची training cutoff असते. त्यामुळे वर्तमानाबद्दलच्या प्रश्नांची उत्तरे देण्यासाठी त्याला live search आवश्यक असते. Commercial search APIs प्रत्येक query साठी शुल्क आकारतात आणि rate limit कडक ठेवतात. तुम्ही आधीच पैसे देत असलेल्या server वर local instance साठी एक container पुरतो. Queries त्या server च्या बाहेर जात नाहीत. Model मध्ये tools जोडत असल्यास, याच कारणामुळे VPS वर MCP servers चालवणे उपयुक्त ठरते. Search tool हे सहसा लोक सर्वप्रथम जोडतात.
API वापरण्यासाठी 2 नियम आहेत. Instance private ठेवा. API side ला loopback address किंवा private network वर bind करा आणि फक्त तुमच्या hosts ना त्याच्यापर्यंत पोहोचू द्या. त्यानंतर queries मर्यादित वेगाने पाठवा. SearXNG तुमची request वास्तविक search engines कडे forward करते. त्यामुळे प्रति सेकंद 100 queries चालवणारी script तुमच्या server ला block करण्यासाठी Google ला कारण देते.
मर्यादक आणि सार्वजनिक instance साठी होणारे बदल
मर्यादक हे SearXNG चे bot संरक्षण आहे. तो request headers, addresses आणि request rates वर लक्ष ठेवतो आणि automated दिसणारा traffic टाकून देतो. ही स्थिती साठवण्यासाठी त्याला Valkey आवश्यक असते. म्हणूनच Compose file मध्ये Valkey समाविष्ट आहे.
खासगी instance वर limiter: false ठेवा. तुमच्या स्वतःच्या scripts मधून येणारा traffic परिभाषेनुसार automated असतो. त्यामुळे instance ज्या JSON calls साठी तयार केला आहे, त्याच calls मर्यादक block करेल. त्याऐवजी access control चे काम reverse proxy कडे द्या: nginx location मधील allow आणि deny ची जोडी, HTTP basic authentication किंवा तुमच्या इतर servers कडून येणारा trafficच स्वीकारणारा firewall वापरा. वेगवेगळ्या networks वर जाणाऱ्या laptop वरून खासगी instance शी संपर्क साधायचा असल्यास त्याच्या पुढे v3 onion address ठेवणे हा चौथा पर्याय आहे. tor नवीन काहीही internet वर उघड न करता त्याच loopback port शी connect करतो.
इतर लोकांसाठी instance प्रकाशित केल्यास दोन्ही switches on करा.
server:
limiter: true
public_instance: trueअधिक सूक्ष्म नियंत्रण core-config/limiter.toml मध्ये असते. container ते /etc/searxng/limiter.toml मधून वाचतो. बदलायच्या keys एवढ्याच लिहा. Proxy च्या मागे असल्यास proxy घोषित करणे आवश्यक आहे. अन्यथा मर्यादक तुमचा nginx address हा गैरवापर करणारा एकमेव client समजतो.
[botdetection]
trusted_proxies = [
'127.0.0.0/8',
'::1',
]
[botdetection.ip_limit]
link_token = truelink_token = true मुळे SearXNG असा token तयार करते, जो फक्त वास्तविक browser session fetch करेल. त्यामुळे साधे scrapers बहुतांश वेळा थांबतात. सार्वजनिक instance कडे काही दिवसांत scrapers आकर्षित होतील, अशी अपेक्षा ठेवा. Engine errors साठीही तयार रहा. तुम्ही जितका अधिक traffic forward कराल, तितक्या लवकर upstream engines तुमच्या server address कडे CAPTCHAs पाठवू लागतील. सार्वजनिक SearXNG instance चालवणे हे सतत करावे लागणारे काम आहे. खासगी instance साठी तसे नाही. म्हणूनच ते 2026 मध्ये self-host करण्यास उपयुक्त गोष्टींच्या बहुतेक छोट्या याद्यांमध्ये असते. त्या याद्यांमधील प्रत्येक entry infrastructure नसते. उदाहरणार्थ, Jellyfin library ला चालत फिरता येईल अशा 90s 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 चे addresses असल्याचे गृहीत धरतात. त्यानंतर SearXNG त्या अपयशी engine ला पुन्हा प्रयत्न करण्याऐवजी काही काळासाठी suspend करते. त्यामुळे एक अवरोधित engine तुमच्या results मधून शांतपणे वगळला जातो. ते settings.yml मध्ये disable करा किंवा ही अनुपलब्धता स्वीकारा. हेच दोन पर्याय नाहीत, कारण काही CAPTCHA blocks साठी restart नंतरही लागू राहणारा उपाय उपलब्ध आहे. उर्वरित engines प्रतिसाद देत राहतात. 429 हे संदिग्ध प्रकरण आहे, कारण ते तुमच्या स्वतःच्या limiter कडून किंवा upstream engine ने तुमचा server नाकारल्यामुळे येऊ शकते. Settings बदलण्यापूर्वी log line तुम्ही या दोन्हीपैकी कोणत्या परिस्थितीकडे पाहत आहात ते सांगते.
सर्व engines एकाच वेळी fail होत असतील, तर container मध्ये कार्यरत outbound name resolution नाही किंवा internet कडे route नाही. Container च्या आतून त्याची चाचणी करा.
docker compose exec core wget -qO- https://duckduckgo.com > /dev/null && echo okही तपासणी fail होऊ लागल्याचे box वरील कोणतीही यंत्रणा तुम्हाला सांगणार नाही. त्यामुळे ती cron मधून चालवा आणि परिणाम कमी झाल्याचे तुमच्या लक्षात येईपर्यंत थांबण्याऐवजी failure झाल्यावर तुमच्या स्वतःच्या ntfy server वरून तुमच्या phone वर alert पाठवा.
FAQ
SearXNG मुळे माझे शोध अनामिक होतात का?
SearXNG ज्या search engines ना query पाठवते, त्यांच्यापासून तुमची ओळख लपवते. कारण त्यांना विनंती तुमच्या browser ऐवजी तुमच्या server कडून आलेली दिसते. मात्र query तुमच्या server पासून लपवत नाही. तसेच तुमचा server त्या search engines पासून लपवत नाही. Single-user instance मध्ये त्या address कडून येणारी सर्व network traffic तुमचीच असते. त्यामुळे तो address स्वतःच identifier बनतो. तुमच्या browser आणि instance मधील traffic TLS certificate मुळे सुरक्षित असते. तुमच्या ISP, public instance चा operator आणि search engines यांच्या संदर्भात याचा नेमका परिणाम SearXNG प्रत्यक्षात काय लपवते येथे स्पष्ट केला आहे.
JSON request मुळे 403 Forbidden का मिळते?
यामागे दोन कारणे असू शकतात आणि दोन्ही configuration शी संबंधित आहेत. एकतर json हे settings.yml मधील search: अंतर्गत असलेल्या formats list मध्ये नाही. ही default state आहे. किंवा limiter सुरू असून त्याने तुमच्या script ला bot म्हणून वर्गीकृत केले आहे. आधी format जोडा. docker compose restart core वापरून restart करा. त्यानंतर पुन्हा प्रयत्न करा. तरीही अपयश येत असल्यास limiter: false सेट करा आणि reverse proxy वर access नियंत्रित करा.
Limiter बंद ठेवत असल्यास Valkey container आवश्यक आहे का?
तो running ठेवा. SearXNG त्याशिवाय कार्य करते. परंतु त्याच्याशिवाय limiter नंतर सुरू करता येत नाही. त्यात इतर अल्पकाळ टिकणारी state देखील ठेवली जाते. Container लहान आहे आणि फक्त cached data साठवतो. त्यामुळे तो काढल्याने फारच कमी बचत होते आणि limiter सुरू करण्याचा पर्याय गमवावा लागतो.
SearXNG कसे update करावे?
/opt/searxng मध्ये आधी docker compose pull आणि नंतर docker compose up -d चालवा. ज्या container ची image बदलली आहे तो container Compose पुन्हा तयार करते. तुमची core-config/ directory तशीच ठेवते. त्यामुळे settings.yml टिकून राहते. use_default_settings: true तुमच्या keys ला shipped defaults वर merge करते. त्यामुळे upstream मध्ये जोडलेले options file मोडण्याऐवजी योग्य values सह उपलब्ध होतात.
अनेक लोक एकच instance share करू शकतात का?
होय. अशा वेळी limiter सुरू करा आणि public_instance: true सेट करा. Preferences प्रत्येक visitor च्या स्वतःच्या browser मध्ये साठवल्या जातात. त्यामुळे accounts व्यवस्थापित करण्याची गरज नसते. Instance सार्वजनिक केल्यानंतर एक आठवडा /stats monitor करा. कारण missing results तुमच्या लक्षात येण्यापूर्वीच upstream search engines तुमचा server reject करू लागतात.