استضافة SearXNG ذاتياً: محرك بحث خاص بك
شغّل SearXNG على VPS خاص عبر Docker Compose، واضبط settings.yml وlimiter وnginx مع TLS، واستدعِ واجهة JSON من نصوصك دون مفتاح API أو فوترة.
ما الذي ستبنيه
يمنحك الاستضافة الذاتية لـSearXNG محرك بحث خاصاً يعمل على خادمك. SearXNG هو محرك بحث تجميعي؛ يأخذ استعلامك، ويرسل طلبات إلى محركات أخرى مثل Google وBing وDuckDuckGo وWikipedia، ثم يدمج النتائج في صفحة نتائج واحدة. لا يُنشئ ملفاً تعريفياً ولا يعيّن ملف تعريف ارتباط للتتبع، لأن جهازك هو الجهاز الوحيد الذي يحتفظ باستعلامك. إذا وجدت أدلة أقدم عن مشروع يُسمى Searx فقط، فهذا هو المشروع الذي تفرّع منه هذا المشروع، ولم يُسجّل أي commit فيه منذ 2023، لذلك تحقق من حالة المشروعين قبل أن تتبع أحدهما.
المكدس صغير. حاويتان، وملف إعدادات واحد، وReverse Proxy واحد. سيعمل بسهولة على VPS صغير، وهذا لا ينطبق على كل خدمة ذاتية الاستضافة: مكتبات الصور التي قورنت في PhotoPrism مقابل Immich تحدد الحد الأدنى لذاكرة RAM وفقاً للفهرس، لا لتطبيق الويب. القرار الفعلي هو ما إذا كانت المثيلة خاصة، أي لا يصل إليها إلا أنت والبرامج النصية الخاصة بك، أو عامة، أي يمكن لأي شخص على الإنترنت إرسال استعلامات إليها. يغيّر هذا الاختيار إعدادات الأمان، لذلك حدده قبل كتابة أي شيء. الخيار الافتراضي هو الوضع الخاص.
هناك سبب ثانٍ لتشغيل مثيلة منها. تتحدث مثيلة SearXNG عبر JSON، لذلك يحصل أي برنامج نصي أو وكيل ذكاء اصطناعي تكتبه على API للبحث تملكه، من دون مفتاح، أو فوترة لكل استعلام، أو رسائل بشأن الحصة.
تثبيت SearXNG باستخدام Docker Compose
ينشر المشروع صورة حاوية وملف Compose. اسحب كليهما إلى خادم Ubuntu 24.04 جديد يحتوي مسبقاً على Docker Engine وCompose plugin. إذا كنت تستخدم Docker للمرة الأولى، فابدأ بقراءة أساسيات Docker Compose على VPS ثم عد إلى هنا.
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 خدمتين. core هو SearXNG نفسه، وvalkey هو مخزن بيانات في الذاكرة يُستخدم لتحديد معدل الطلبات ولحفظ الحالة قصيرة الأجل. يربط الملف ./core-config/ بالمسار /etc/searxng/ داخل الحاوية، لذلك توجد كل الإعدادات التي تضبطها في هذا الدليل الواحد على الخادم المضيف.
حرّر الآن .env. كل سطر في المثال المرفق معلّق بعلامة تعليق، ولذلك تبدأ الحاوية بالاستماع على المنفذ 8080 على كل العناوين. أزل علامة التعليق واضبط هذه القيم الثلاث.
SEARXNG_VERSION=latest
SEARXNG_HOST=127.0.0.1
SEARXNG_PORT=8080يُعد SEARXNG_HOST=127.0.0.1 الإعداد الأهم. فهو يجعل المنفذ المنشور 127.0.0.1:8080:8080 بدلاً من [::]:8080:8080، لذلك لا تستجيب الحاوية إلا على عنوان loopback، ولا يستطيع الإنترنت الوصول إليها مباشرة. إذا تخطيت هذا الإعداد، فستصبح الحاوية مكشوفة فور بدء تشغيلها، لأن منفذ Docker المنشور يُدرج قبل قواعد جدارك الناري. اقرأ شرح هذا الخطأ بالكامل: منافذ Docker المنشورة تتجاوز ufw.
يُعد SEARXNG_VERSION=latest مناسباً أثناء تعلّمك. أما على خادم مهم، فثبّت الوسم. اعتباراً من July 2026، تعتمد وسوم الإصدارات على التاريخ وتظهر بالشكل 2026.3.25-541c6c3cb، ولذلك لا يُرقّى النشر المثبّت إلا عندما تقرر أنت ذلك، وليس عند تغيّر السجل دون علمك. وينطبق الانضباط نفسه على أي خدمة أخرى طويلة الأجل على الخادم، ولذلك يثبّت مرحل RustDesk المستضاف ذاتياً وسوم صوره أيضاً؛ فالترقية غير المراقبة لخدمة وصول عن بُعد تعلن عن نفسها في أسوأ وقت ممكن.
الأجزاء المهمة من settings.yml
أنشئ core-config/settings.yml قبل التشغيل الأول. يطلب use_default_settings: true من SearXNG تحميل الإعدادات الافتراضية المضمّنة فيه، ثم تطبيق المفاتيح التي كتبتها فقط. لذلك يبقى ملفك قصيراً ويستمر في العمل بعد الترقيات التي تضيف خيارات جديدة.
ولّد السر أولاً، لأن القيمة ستُكتب مباشرةً في الملف.
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
- jsonيستخدم secret_key لتوقيع بيانات الجلسات والرموز المميّزة. القيمة الافتراضية المضمّنة هي السلسلة الحرفية ultrasecretkey. إذا تركتها، فبإمكان أي شخص يعرف هذه القيمة الافتراضية تزوير تلك الرموز. استبدلها مرة واحدة ثم لا تغيّرها، لأن تغييرها لاحقاً يحذف كل التفضيلات المحفوظة.
يجب أن يكون base_url عنوان HTTPS العام، مع الشرطة المائلة النهائية. يستخدمه SearXNG لكتابة الروابط التي يعرضها. إذا تركته يشير إلى localhost، فسيشير رابط "الصفحة التالية" في المتصفح البعيد إلى جهاز القارئ نفسه وسيفشل.
يحدّد formats أنواع المخرجات التي ستنتجها نقطة نهاية الويب. لا يوجد json في القائمة الافتراضية، لذلك يعيد طلب JSON رمز الحالة 403 إلى أن تضيفه. يمرّر image_proxy: true الصور المصغّرة للنتائج عبر خادمك، ولذلك لا ترى المواقع التي تستضيف تلك الصور عناوين زوارك.
يستخدم valkey.url اسم المضيف valkey، لأن هذا هو اسم الخدمة في ملف Compose. يضع Compose كلا الحاويتين على شبكة واحدة، حيث يمكن حل أسماء الخدمات. إذا وجّهته إلى localhost، فسيفشل محدِّد المعدل، لأن localhost داخل حاوية core يشير إلى تلك الحاوية نفسها.
يوجد السر في ملف عادي، لذلك احمِ المجلد المحيط به بدلاً من حماية الملف نفسه. يمنع 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، لأن خطأ YAML في settings.yml سيظهر هناك كخطأ في التحليل يذكر رقم السطر.
ضعه خلف nginx مع TLS
يستمع الحاوي على loopback فقط، لذلك يتيح nginx الوصول إليه، وهو يضيف أيضاً أمان طبقة النقل (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 قيمتي syntax is ok وtest is successful قبل إعادة التحميل. يعيد Certbot كتابة الملف نفسه للاستماع على 443 باستخدام شهادة، ويضيف إعادة توجيه من المنفذ 80. يجب أن يشير سجل DNS الخاص بـ search.example.com إلى هذا الخادم مسبقاً، لأن المرجع المصدّق يثبت الملكية من خلال جلب ملف عبر HTTP. يرد الشرح الكامل، بما في ذلك التجديد، في دليل Certbot وnginx لنظام Ubuntu 24.04.
رأسا إعادة التوجيه ليسا للزينة. من دون X-Forwarded-For وX-Real-IP، يصل كل طلب إلى SearXNG حاملاً عنوان الوكيل، لذلك يرى محدِّد المعدل عميلاً واحداً يرسل كل حركة الشبكة، ولا يستطيع التمييز بين الزوار.
لماذا تحتاج البرامج النصية والوكلاء إلى واجهة JSON للبحث
باستخدام 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. وهذا يكفي لتغذية أداة تلخيص، أو مدقّق روابط، أو حلقة بحث. وتمرير هذه النتائج إلى نموذج لغوي خطوة أكبر مما تبدو عليه، لأن نتائج البحث نص غير موثوق قد يتضمن تعليمات خاصة به. وهذا ما توضحه بالتفصيل توجيه وكيل ذكاء اصطناعي إلى مثيل SearXNG لديك.
يهم ذلك كل ما يعتمد على الوكلاء. يملك النموذج اللغوي تاريخاً فاصلاً لبيانات التدريب، لذلك يحتاج إلى بحث مباشر للإجابة عن أسئلة تتعلق بالحاضر. كما تفرض واجهات البحث التجارية رسوماً على كل استعلام وتطبّق حدوداً صارمة لمعدل الطلبات. أما المثيل المحلي، فيحتاج إلى حاوية واحدة على خادم تدفع تكلفته مسبقاً، ولا تغادره الاستعلامات. وإذا كنت تربط أدوات بنموذج، فإن المنطق نفسه يقود إلى تشغيل خوادم MCP على VPS، إذ تكون أداة البحث عادةً أول أداة يضيفها المستخدمون.
هناك قاعدتان لاستخدام API. اجعل المثيل خاصاً. اربط جانب API بعنوان loopback أو بشبكة خاصة، ولا تسمح بالوصول إليه إلا من مضيفاتك. ثم أرسل الاستعلامات بمعدل منخفض. يمرّر SearXNG طلبك إلى محركات البحث الفعلية، لذلك فإن تشغيل نص برمجي يرسل مئة استعلام في الثانية يعني أنك تطلب من Google حظر خادمك.
المحدِّد، وما الذي يتغير عند إتاحة المثيل للعامة
المحدِّد هو آلية SearXNG للدفاع ضد الروبوتات. يراقب رؤوس الطلبات والعناوين ومعدلات الطلبات، ويحذف حركة الشبكة التي تبدو آلية. يحتاج إلى Valkey لتخزين هذه الحالة، ولذلك يتضمنها ملف Compose.
في المثيل الخاص، أبقِ limiter: false. تُعدّ نصوصك البرمجية حركة شبكة آلية بحكم التعريف، ولذلك سيحظر المحدِّد طلبات JSON نفسها التي أنشأت المثيل من أجلها. تكون مهمة التحكم في الوصول للـReverse Proxy بدلاً من ذلك: زوج allow وdeny في location الخاص بـnginx، أو مصادقة HTTP الأساسية، أو جدار ناري لا يسمح إلا بخوادمك الأخرى. إذا احتجت إلى الوصول إلى مثيل خاص من حاسوب محمول ينتقل بين الشبكات، فإن وضع عنوان onion من الإصدار v3 أمامه خيار رابع، لأن Tor يتصل بمنفذ loopback نفسه دون تعريض أي شيء جديد للإنترنت.
إذا أتحت المثيل للعامة، فعِّل المفتاحين.
server:
limiter: true
public_instance: trueيوفّر core-config/limiter.toml تحكماً أدق، ويقرأه الحاوي في /etc/searxng/limiter.toml. اكتب المفاتيح التي تريد تغييرها فقط. عند استخدام Proxy، يجب أن تعرّف الـProxy، وإلا فسيتعامل المحدِّد مع عنوان nginx على أنه عنوان العميل المسيء.
[botdetection]
trusted_proxies = [
'127.0.0.0/8',
'::1',
]
[botdetection.ip_limit]
link_token = trueيجعل link_token = true SearXNG يصدر رمزاً مميزاً لا تجلبه إلا جلسة متصفح حقيقية، مما يوقف معظم أدوات الكشط البسيطة. توقّع أن تجذب هذه الأدوات المثيل العام خلال أيام. وتوقّع أيضاً أخطاء من المحركات، لأن زيادة حركة الشبكة التي تمررها تسرّع بدء المحركات upstream في إعادة اختبارات CAPTCHA إلى عنوان خادمك. تشغيل مثيل SearXNG عام مهمة مستمرة. أما المثيل الخاص فلا يتطلب ذلك، ولذلك يظهر في معظم القوائم المختصرة لـالأشياء التي تستحق الاستضافة الذاتية في 2026. ولا تتعلق كل العناصر في تلك القوائم بالبنية التحتية: إعادة بناء مكتبة Jellyfin على هيئة متجر تأجير من التسعينيات يمكن التجول فيه تعني استخدام الحاوي نفسه خلف كتلة nginx نفسها، مع توجيهه إلى أمسية بدلاً من سير عمل.
لماذا لا تُرجع عمليات البحث أي نتائج
افتح /stats على نسختك. يعرض هذا الملف كل محرك مع معدل أخطائه وزمن استجابته، وهو أول مكان يجب فحصه عندما تبدو النتائج قليلة.
المحرّك الذي يعرض أخطاء مثل "Access denied" أو "CAPTCHA" حظر عنوان خادمك. يحدث ذلك كثيراً للعناوين الواقعة ضمن نطاقات مراكز البيانات، لأن محركات البحث تفترض أنها تخص أدوات استخراج البيانات. يعلّق SearXNG المحرّك الذي فشل لمدة معينة بدلاً من إعادة محاولة الطلب، لذلك يختفي أحد المحركات المحظورة من نتائجك بهدوء. عطّله في settings.yml أو اقبل فقدانه. لكن هذين ليسا الخيارين الوحيدين، لأن بعض عمليات حظر CAPTCHA لها معالجة تستمر بعد إعادة التشغيل. تظل المحركات الأخرى تستجيب. أما الخطأ 429 فهو الحالة الملتبسة، لأنه قد يصدر عن محدِّد المعدل لديك أو عن محرّك upstream يرفض خادمك، ويوضح سطر السجل أي الاحتمالين ينطبق عليك قبل أن تبدأ بتغيير الإعدادات.
إذا تعطلت كل المحركات في الوقت نفسه، فلن تكون الحاوية قادرة على حل أسماء النطاقات الصادرة أو لن يكون لديها مسار إلى الإنترنت. اختبر ذلك من داخل الحاوية.
docker compose exec core wget -qO- https://duckduckgo.com > /dev/null && echo okلن يخبرك أي شيء على الخادم ببدء فشل هذا الفحص، لذلك شغّله من cron ودَع الفشل يرسل تنبيهاً إلى هاتفك من خادم ntfy الخاص بك بدلاً من الانتظار حتى تلاحظ أن النتائج أصبحت قليلة.
FAQ
هل يجعل SearXNG عمليات البحث التي أجريها مجهولة؟
يخفي هويتك عن محركات البحث التي يستعلم منها، لأنها ترى خادمك يرسل الطلب بدلاً من متصفحك. لكنه لا يخفي الاستعلام عن خادمك، ولا يخفي خادمك عنها. في نسخة مخصصة لمستخدم واحد، تكون كل حركة المرور من ذلك العنوان صادرة منك، لذلك يصبح العنوان نفسه معرّفاً. تحمي شهادة TLS حركة المرور بين متصفحك ونسختك. يوضّح ما الذي يخفيه SearXNG فعلياً كيفية تأثير ذلك في علاقتك بموفر خدمة الإنترنت، ومشغّل النسخة العامة، ومحركات البحث نفسها.
لماذا يعيد طلب JSON الاستجابة 403 Forbidden؟
هناك سببان، وكلاهما متعلق بالإعدادات. إما أن json مفقود من قائمة formats ضمن search: في settings.yml، وهي الحالة الافتراضية، أو أن أداة الحد من المعدل مفعّلة وقد صنّفت برنامجك النصي على أنه bot. أضف التنسيق أولاً، ثم أعد التشغيل باستخدام docker compose restart core، وحاول مرة أخرى. إذا استمر الفشل، اضبط limiter: false وتحكم في الوصول من خلال الـreverse proxy بدلاً من ذلك.
هل أحتاج إلى حاوية Valkey إذا أبقيت أداة الحد من المعدل متوقفة؟
اتركها قيد التشغيل. يعمل SearXNG من دونها، لكن لا يمكن تفعيل أداة الحد من المعدل لاحقاً من دونها، كما أنها تخزن حالة أخرى قصيرة الأجل. الحاوية صغيرة ولا تخزن إلا بيانات مخزنة مؤقتاً، لذلك لا تؤدي إزالتها إلا إلى توفير قليل جداً، وتحرمك من هذا الخيار.
كيف أحدّث SearXNG؟
شغّل docker compose pull ثم docker compose up -d في /opt/searxng. يعيد Compose إنشاء أي حاوية تغيّرت صورتها، ويترك دليل core-config/ من دون تغيير، لذلك تبقى settings.yml. وبما أن use_default_settings: true يدمج مفاتيحك فوق الإعدادات الافتراضية التي يأتي بها البرنامج، تصل الخيارات المضافة upstream بقيم مناسبة بدلاً من التسبب في تعطل الملف.
هل يمكن لعدة أشخاص مشاركة نسخة واحدة؟
نعم، وهذه هي الحالة التي تفعّل فيها أداة الحد من المعدل وتضبط public_instance: true. تُخزَّن التفضيلات في متصفح كل زائر، لذلك لا توجد حسابات لإدارتها. راقب /stats لمدة أسبوع بعد إتاحتها، لأن محركات البحث upstream تبدأ برفض خادمك قبل وقت طويل من ملاحظتك اختفاء النتائج.