SSD Nodes Learn Hosting plans →
الأدلة Matt Connorبقلم Matt Connor

كيفية تشغيل SearXNG خاصاً على خادمك باستخدام Docker

شغّل SearXNG على VPS خاص باستخدام Docker Compose، واضبط settings.yml وlimiter وnginx مع TLS، ثم استخدم JSON API لاستدعاء البحث من سكربتاتك.

ما الذي ستبنيه

يمنحك تشغيل SearXNG ذاتياً محرك بحث خاصاً يعمل على خادمك. SearXNG هو محرك بحث تجميعي؛ يأخذ استعلامك، ويرسله إلى محركات أخرى مثل Google وBing وDuckDuckGo وWikipedia، ثم يدمج النتائج الواردة في صفحة نتائج واحدة. لا يُنشأ ملف تعريفي ولا تُعيَّن cookie للتتبع، لأن جهازك هو الجهاز الوحيد الذي يحتفظ باستعلامك. إذا وجدت أدلة أقدم لشيء يُسمى Searx فقط، فهذا هو المشروع الذي تفرّع منه هذا المشروع. لم تتم صيانته منذ September 2023، عندما أعلن مستودعه نفسه أن Searx لم يعد قيد الصيانة. كما أن الالتزام الوحيد منذ ذلك الحين، وهو ملاحظة توثيقية في May 2026، لم يغيّر ذلك. لذلك تحقق من حالة كليهما قبل أن تتبع أحدهما.

المكدس صغير. حاويتان، وملف إعداد واحد، و reverse proxy واحد. سيعمل بسهولة على VPS صغير مشترك، لكن هذا لا ينطبق على كل خدمة مستضافة ذاتياً: فقد حدّدت مكتبتا الصور المقارنتان في PhotoPrism مقابل Immich الحد الأدنى لاستهلاك RAM وفقاً للفهرس لا لتطبيق الويب. القرار الفعلي هو ما إذا كانت النسخة خاصة، أي لا يصل إليها سواك أنت والبرامج النصية الخاصة بك، أو عامة، أي يستطيع أي شخص على الإنترنت إرسال استعلامات إليها. يغيّر هذا الاختيار إعدادات الأمان، لذلك حدده قبل أن تكتب أي شيء. والإجابة الافتراضية هي أن تكون خاصة.

هناك سبب ثانٍ لتشغيل نسخة منها. تتحدث نسخة SearXNG عبر JSON، لذلك يحصل أي برنامج نصي أو وكيل AI تكتبه على Search API تملكه، من دون key أو فوترة لكل استعلام أو رسائل quota.

ثبّت SearXNG باستخدام Docker Compose

ينشر المشروع صورة حاوية وملف Compose. اسحب كليهما إلى خادم Ubuntu 24.04 جديد يحتوي مسبقاً على Docker Engine وإضافة Compose. إذا لم تكن معتاداً على 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 مجرداً، لأن Docker ينشر المنفذ المجرّد على كل العناوين. لذلك لا تستجيب الحاوية إلا على عنوان loopback، ولا يستطيع الإنترنت الوصول إليها مباشرة. إذا تخطيت هذا الإعداد، تصبح الحاوية مكشوفة فور بدء تشغيلها، لأن منفذ Docker المنشور يُضاف قبل قواعد جدارك الناري. اقرأ هذا الفخ بالتفصيل: منافذ Docker المنشورة تتجاوز ufw.

يُعد SEARXNG_VERSION=latest مناسباً أثناء تعلّمك. أما على خادم مهم، فثبّت الوسم. اعتباراً من October 2026، تعتمد وسوم الإصدارات على التاريخ وتبدو مثل 2026.10.4-d48c4b555، لذلك لا تُحدّث عملية النشر المثبتة إلا عندما تقرر ذلك، وليس عندما يتغير السجل من تلقاء نفسه. وينطبق الانضباط نفسه على أي مكوّن آخر يعمل لفترة طويلة على الخادم، ولذلك يثبت مرحل RustDesk المستضاف ذاتياً وسوم صوره أيضاً؛ فالترقية غير المراقبة لخدمة وصول عن بُعد تعلن عن نفسها في أسوأ وقت ممكن.

settings.yml: الأجزاء المهمة

أنشئ core-config/settings.yml قبل التشغيل الأول. يخبر use_default_settings: true ‏SearXNG بتحميل الإعدادات الافتراضية المضمّنة معه، ثم تطبيق المفاتيح التي كتبتها فقط. لذلك يبقى ملفك قصيراً ويستمر بالعمل بعد الترقيات التي تضيف خيارات جديدة.

ولّد السر أولاً، لأن القيمة ستُكتب مباشرةً في الملف.

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 بيانات الجلسات والرموز. القيمة الافتراضية المضمّنة هي السلسلة الحرفية 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 دون التسبب في أي مشكلة. تبدأ نقطة دخول الحاوية الرسمية بصلاحيات root، ومع بقاء FORCE_OWNERSHIP على قيمته الافتراضية true، تسلّم دليل الإعداد الموصول إلى مستخدم الحاوية searxng قبل بدء SearXNG، لذلك يظل الملف قابلاً للقراءة من ذلك المستخدم. يظهر الأثر الجانبي على المضيف: تغيّر الخطوة نفسها مالك core-config/ إلى معرّف مستخدم الحاوية، لذلك توقّع أن تعدّل الملف باستخدام sudo بعد ذلك.

شغّل المكدس وتحقق منه.

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 عنوان الوكيل، لذلك يرى محدِّد المعدل عميلاً واحداً يرسل كل حركة المرور، ولا يستطيع تمييز الزوار عن بعضهم.

لماذا تحتاج السكربتات والوكلاء إلى واجهة 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. وهذا يكفي لتغذية أداة تلخيص، أو أداة للتحقق من الروابط، أو حلقة بحث. وتمرير هذه النتائج إلى نموذج لغوي خطوة أكبر مما تبدو عليه، لأن نتائج البحث نص غير موثوق قد يحتوي على تعليمات خاصة به. وهذا ما تتناوله بالتفصيل إتاحة مثيل SearXNG لوكيل ذكاء اصطناعي.

هذا مهم لكل ما يتعلق بالوكلاء. يمتلك النموذج اللغوي تاريخاً فاصلاً لبيانات التدريب، لذلك يحتاج إلى بحث مباشر للإجابة عن أسئلة تتعلق بالحاضر. كما تفرض واجهات API التجارية للبحث رسوماً على كل استعلام وتطبّق حدوداً صارمة على المعدل. أما المثيل المحلي فيستهلك حاوية واحدة على خادم تدفع تكلفته مسبقاً، ولا تغادره الاستعلامات. وإذا كنت توصل الأدوات بنموذج، فإن المنطق نفسه ينطبق على تشغيل خوادم MCP على VPS، إذ تكون أداة البحث عادةً أول أداة يضيفها المستخدمون.

هناك قاعدتان لاستخدام API. اجعل المثيل خاصاً. اربط جانب API بعنوان loopback أو بشبكة خاصة، واسمح فقط لخوادمك بالوصول إليه. وينطبق الإجراء نفسه على متعقب مواقع مستضاف ذاتياً، الذي يحتاج إلى حماية نقطة النهاية التي يرسل إليها هاتفك موقعه. ثم أرسل الاستعلامات بمعدل منخفض. يمرر SearXNG طلبك إلى محركات بحث فعلية، ولذلك فإن تشغيل سكربت يرسل مئة استعلام في الثانية يعني أنك تطلب من Google حظر خادمك.

المحدِّد، وما الذي يتغير في النسخة العامة

المحدِّد هو آلية SearXNG للدفاع ضد الروبوتات. يراقب رؤوس الطلبات والعناوين ومعدلات الطلبات، ويحذف حركة الشبكة التي تبدو آلية. يحتاج إلى Valkey لتخزين هذه الحالة، ولذلك يتضمنها ملف Compose.

في النسخة الخاصة، أبقِ limiter: false. تُعدّ نصوصك البرمجية حركة شبكة آلية بحكم تعريفها، ولذلك سيحظر المحدِّد طلبات JSON التي أنشأت النسخة من أجلها تحديداً. تكون مهمة التحكم في الوصول من اختصاص الـReverse Proxy بدلاً من ذلك: زوج allow وdeny في location الخاص بـnginx، أو مصادقة HTTP الأساسية، أو جدار ناري لا يسمح إلا بخوادمك الأخرى. إذا احتجت إلى الوصول إلى نسخة خاصة من حاسوب محمول ينتقل بين الشبكات، فإن وضع عنوان onion من الإصدار 3 أمامها خيار رابع، لأن Tor يتصل بمنفذ loopback نفسه من دون تعريض أي شيء جديد للإنترنت.

إذا نشرت النسخة ليستخدمها أشخاص آخرون، فعِّل المفتاحين معاً.

server:
  limiter: true
  public_instance: true

توجد إعدادات أدق في core-config/limiter.toml، الذي يقرأه الحاوي من /etc/searxng/limiter.toml. اكتب المفاتيح التي تريد تغييرها فقط. عند استخدام Proxy، يجب أن تصرّح به، وإلا فسيعتبر المحدِّد عنوان nginx هو العميل المسيء.

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

[botdetection.ip_limit]
link_token = true

يجعل link_token = true SearXNG يُصدر رمزاً لا تجلبه إلا جلسة متصفح حقيقية، ما يوقف معظم أدوات الاستخراج البسيطة. توقّع أن تجتذب النسخة العامة هذه الأدوات خلال أيام. وتوقّع أيضاً أخطاء من المحركات، لأن زيادة حركة الشبكة التي تمررها تسرّع بدء المحركات الخارجية في إعادة CAPTCHA إلى عنوان خادمك. تشغيل نسخة عامة من SearXNG مهمة مستمرة. أما النسخة الخاصة فلا تتطلب ذلك، ولهذا تظهر في معظم القوائم المختصرة لـالأشياء التي تستحق الاستضافة الذاتية في 2026. ولا تكون كل العناصر في هذه القوائم من البنية التحتية أيضاً: فـإعادة بناء مكتبة Jellyfin كمتجر تأجير من حقبة التسعينيات يمكن التجول فيه هي الحاوي نفسه خلف كتلة nginx نفسها، لكنها موجهة إلى أمسية بدلاً من سير عمل.

سبب عدم ظهور أي نتائج في عمليات البحث

افتح /stats على نسختك. يعرض هذا الملف كل محرك مع معدل أخطائه وزمن استجابته، وهو أول مكان يجب فحصه عندما تبدو النتائج محدودة.

إذا ظهر محرك مع أخطاء مثل "Access denied" أو "CAPTCHA"، فهذا يعني أنه حظر عنوان خادمك. يحدث ذلك كثيراً للعناوين الموجودة ضمن نطاقات مراكز البيانات، لأن محركات البحث تفترض أن هذه العناوين تخص أدوات جمع البيانات. يعلّق SearXNG بعد ذلك المحرك الذي يفشل لفترة بدلاً من إعادة المحاولة، ولذلك يختفي محرك محظور من النتائج دون تنبيه واضح. عطّله في settings.yml أو اقبل فقدانه. لكن هذين ليسا الخيارين الوحيدين، لأن بعض عمليات حظر CAPTCHA لها معالجة تستمر بعد إعادة التشغيل. تظل المحركات الأخرى تستجيب. أما الخطأ 429 فهو الحالة الملتبسة، لأنه قد يصدر عن المحدِّد الموجود لديك أو عن محرك خارجي يرفض خادمك، ويوضح سطر السجل أيّ الاحتمالين تواجهه قبل أن تبدأ بتغيير الإعدادات.

إذا فشلت كل المحركات في الوقت نفسه، فلن تكون الحاوية قادرة على حل أسماء النطاقات الصادرة أو لن يكون لديها مسار إلى الإنترنت. اختبر ذلك من داخل الحاوية.

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 يدمج مفاتيحك فوق الإعدادات الافتراضية التي يأتي بها الإصدار، تصل الخيارات المضافة في الإصدارات الأحدث بقيم مناسبة بدلاً من التسبب في تعطل الملف.

هل يمكن لعدة أشخاص مشاركة نسخة واحدة؟

نعم، وهذه هي الحالة التي تفعّل فيها أداة تحديد المعدل وتعيّن public_instance: true. تُخزَّن التفضيلات في متصفح كل زائر، لذلك لا توجد حسابات تحتاج إلى إدارتها. راقب /stats لمدة أسبوع بعد إتاحتها، لأن محركات البحث تبدأ برفض خادمك قبل وقت طويل من ملاحظتك اختفاء النتائج.