SSD Nodes Learn Hosting plans →
מדריכים Matt Connorמאת Matt Connor · עודכן 2026-09-05

איך להקים SearXNG פרטי ב־VPS עם Docker Compose

מדריך מעשי להפעלת SearXNG ב־VPS באמצעות Docker Compose: הגדרת settings.yml, limiter, nginx עם TLS וממשק JSON שסקריפטים יכולים להפעיל ללא מפתח API.

מה אתם בונים

אירוח עצמי של SearXNG מספק לכם מנוע חיפוש פרטי שפועל בשרת שלכם. SearXNG הוא מנוע חיפוש־על: הוא מקבל את השאילתה שלכם, פונה למנועים אחרים כגון Google, Bing, DuckDuckGo ו־Wikipedia, ולאחר מכן ממזג את התוצאות לדף תוצאות אחד. לא נבנה פרופיל ולא מוגדרת עוגיית מעקב, משום שהמחשב היחיד ששומר את השאילתה שלכם הוא המחשב שלכם. אם מצאתם מדריכים ישנים עבור פרויקט שנקרא פשוט Searx, זהו הפרויקט שממנו נוצר המזלג הנוכחי, ולא נרשם בו commit מאז 2023, לכן בדקו את מצבם של שני הפרויקטים לפני שתבחרו באחד מהם.

המחסנית קטנה. שני containers, קובץ הגדרות אחד ו־reverse proxy אחד. היא תפעל ללא קושי לצד שירותים אחרים ב־VPS קטן, בניגוד לכל שירות self-hosted: ספריות התמונות שנבחנו בהשוואה בין PhotoPrism ל־Immich קובעות את דרישת ה־RAM המזערית לפי ה־indexer ולא לפי יישום ה־web. ההחלטה החשובה היא אם המופע יהיה פרטי, כלומר רק אתם והסקריפטים שלכם יוכלו לגשת אליו, או ציבורי, כלומר כל משתמש באינטרנט יוכל לשלוח אליו שאילתות. הבחירה הזו משנה את הגדרות האבטחה, לכן קבלו אותה לפני שתקלידו דבר. ברירת המחדל היא מופע פרטי.

יש סיבה נוספת להפעיל מופע כזה. מופע SearXNG מספק ממשק JSON, ולכן כל סקריפט או agent מבוסס AI שתכתבו יקבל API לחיפוש שנמצא בבעלותכם, ללא key, ללא חיוב לפי שאילתה וללא הודעות על מכסת שימוש.

התקנת SearXNG באמצעות Docker Compose

הפרויקט מפרסם image של container וקובץ 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/ בתוך ה־container, ולכן כל ההגדרות שלכם נמצאות בתיקייה אחת זו בשרת.

כעת ערכו את .env. כל שורה בדוגמה שסופקה מסומנת כהערה, ולכן ה־container מתחיל להאזין על פורט 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, ולכן ה־container עונה רק בכתובת loopback והאינטרנט אינו יכול להגיע אליו ישירות. אם תדלגו על כך, ה־container ייחשף מיד עם הפעלתו, משום שפורט Docker מפורסם מוכנס לפני כללי ה־firewall שלכם. כדאי לקרוא את ההסבר המלא למלכודת הזו: פורט Docker מפורסם עוקף את ufw.

SEARXNG_VERSION=latest מתאים בזמן הלמידה. בשרת שחשוב לכם, קבעו tag מפורש. נכון ליולי 2026, תגי ה־release מבוססים על תאריך ונראים כמו 2026.3.25-541c6c3cb, ולכן deployment מקובע מתעדכן כאשר אתם מחליטים, ולא כאשר ה־registry משתנה ללא ידיעתכם. אותה שיטת עבודה מועילה גם לכל רכיב אחר שפועל לאורך זמן בשרת, ולכן relay של RustDesk באירוח עצמי מקבע גם את תגי ה־image שלו: שדרוג ללא השגחה של שירות גישה מרחוק מודיע על עצמו ברגע הגרוע ביותר.

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 חותם על נתוני session ועל נתוני token. ברירת המחדל שסופקה היא המחרוזת המילולית ultrasecretkey. אם משאירים אותה, כל מי שמכיר את ברירת המחדל יכול לזייף את ה־tokens האלה. החליפו אותה פעם אחת, ולאחר מכן השאירו אותה ללא שינוי: שינוי שלה בהמשך מוחק את כל ההעדפות שנשמרו.

base_url חייב להיות כתובת ה־HTTPS הציבורית, כולל ה־slash שבסופה. זו הכתובת ש־SearXNG כותב בקישורים שהוא מייצר. אם משאירים אותה כשהיא מפנה ל־localhost, הקישור ל־"next page" בדפדפן מרוחק מפנה למחשב של המשתמש עצמו ונכשל.

formats קובע אילו סוגי פלט נקודת הקצה של האינטרנט תייצר. json אינו מופיע ברשימת ברירות המחדל, ולכן בקשת JSON מחזירה 403 עד שמוסיפים אותו. image_proxy: true מנתב את התמונות הממוזערות של תוצאות החיפוש דרך השרת שלכם, כך שהאתרים שמארחים את התמונות האלה אינם רואים את הכתובות של המבקרים שלכם.

ה־valkey.url משתמש בשם המארח valkey, משום שזהו שם השירות בקובץ Compose, ו־Compose מציב את שני ה־containers באותה רשת שבה שמות שירותים נפתרים. אם תפנו אותו אל localhost, ה־limiter ייכשל, משום שבתוך ה־container של core, localhost הוא ה־container עצמו.

הסוד נמצא בקובץ רגיל, לכן הגנו על התיקייה שמכילה אותו ולא על הקובץ עצמו. chmod 750 /opt/searxng מונע ממשתמשים אחרים ב־host לגשת אליו. אל תצמצמו את core-config/settings.yml ל־mode 600: ה־container פועל כמשתמש משלו ללא הרשאות, וקובץ שאינו יכול לקרוא מונע מ־SearXNG לעלות בכלל.

הפעילו את ה־stack ובדקו אותו.

cd /opt/searxng
docker compose up -d
docker compose ps
curl -I http://127.0.0.1:8080/

docker compose ps אמור להציג את שני ה־containers במצב running. ה־curl אמור להשיב HTTP/1.1 200 OK. אם אינו משיב דבר, קראו את docker compose logs core, משום ששגיאת YAML ב־settings.yml תופיע שם כשגיאת parse שמציינת את השורה.

הציבו אותו מאחורי 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 כוללת את כתובת ה־proxy, ולכן מגביל הקצב רואה לקוח אחד שמייצר את כל התעבורה ואינו יכול להבחין בין המבקרים.

מדוע סקריפטים וסוכנים זקוקים ל־API לחיפוש 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. די בכך כדי להזין מסכם, בודק קישורים או לולאת מחקר. העברת התוצאות האלה למודל שפה היא צעד משמעותי יותר מכפי שנדמה, משום שתוצאות חיפוש הן טקסט לא מהימן שעלול לכלול הוראות משלו. בנושא הזה עוסק בפירוט הפניית סוכן AI אל מופע ה־SearXNG שלכם.

הדבר חשוב לכל מערכת המבוססת על סוכנים. למודל שפה יש מועד חיתוך לנתוני האימון, ולכן הוא זקוק לחיפוש בזמן אמת כדי לענות על שאלות הנוגעות להווה. בנוסף, ממשקי חיפוש מסחריים גובים תשלום עבור כל שאילתה ומגבילים את קצב הבקשות באופן נוקשה. מופע מקומי דורש מכולה אחת בשרת שאתם כבר משלמים עליו, והשאילתות אינן עוזבות אותו. אם אתם מחברים כלים למודל, אותו שיקול מוביל ל־הפעלת שרתי MCP ב־VPS, כאשר כלי חיפוש הוא בדרך כלל הכלי הראשון שמוסיפים.

שני כללים לשימוש ב־API. שמרו את המופע פרטי: קשרו את צד ה־API לכתובת loopback או לרשת פרטית, ואפשרו רק למארחים שלכם לגשת אליו. לאחר מכן שלחו שאילתות בקצב מתון. SearXNG מעביר את הבקשה שלכם למנועי חיפוש אמיתיים, ולכן סקריפט שמריץ מאה שאילתות בשנייה למעשה מבקש מ־Google לחסום את השרת שלכם.

המגביל, ומה משתנה במופע ציבורי

המגביל הוא מנגנון ההגנה של SearXNG מפני בוטים. הוא עוקב אחר כותרות הבקשות, הכתובות וקצב הבקשות, ומשליך תעבורה שנראית אוטומטית. הוא זקוק ל־Valkey כדי לשמור את המצב הזה, ולכן הוא נכלל בקובץ Compose.

במופע פרטי השאירו את limiter: false. הסקריפטים שלכם הם תעבורה אוטומטית מעצם הגדרתם, ולכן המגביל יחסום דווקא את קריאות ה־JSON שלשמן הקמתם את המופע. בקרת הגישה היא תפקידו של ה־reverse proxy: זוג allow ו־deny ב־location של nginx, אימות בסיסי של HTTP, או firewall שמאפשר חיבורים רק מהשרתים האחרים שלכם. אם אתם צריכים לגשת למופע פרטי ממחשב נייד שעובר בין רשתות, הצבת כתובת 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 להנפיק אסימון שרק הפעלת דפדפן אמיתית תוריד, וכך מונע את רוב הסורקים הפשוטים. צפו שמופע ציבורי ימשוך אותם בתוך ימים. צפו גם לשגיאות ממנועי החיפוש, משום שככל שתעבירו יותר תעבורה, כך מנועי החיפוש במעלה הזרם יתחילו להחזיר CAPTCHA לכתובת השרת שלכם מוקדם יותר. מופע SearXNG ציבורי דורש תחזוקה שוטפת. מופע פרטי אינו דורש זאת, ולכן הוא מופיע ברוב הרשימות הקצרות של דברים שכדאי לארח באופן עצמאי ב־2026. גם לא כל פריט ברשימות האלה הוא תשתית: בנייה מחדש של ספריית Jellyfin כחנות השכרת קלטות שאפשר לטייל בה משנות ה־90 היא אותה מכולה מאחורי אותו בלוק nginx, כשהיא מצביעה על ערב מסוים במקום על תהליך עבודה.

מדוע חיפושים אינם מחזירים תוצאות

פתחו את /stats ב־instance שלכם. הוא מציג את כל המנועים, את שיעור השגיאות שלהם ואת זמן התגובה שלהם. זהו המקום הראשון לבדוק כאשר נראה שמספר התוצאות נמוך.

מנוע שמציג שגיאות "Access denied" או "CAPTCHA" חסם את כתובת השרת שלכם. מצב זה נפוץ בכתובות מטווחים של מרכזי נתונים, משום שמנועי חיפוש מניחים שהן שייכות לסורקים. לאחר מכן SearXNG משעה את המנוע שכשל למשך פרק זמן, במקום לנסות שוב. לכן מנוע חסום אחד נעלם בשקט מתוצאות החיפוש. השביתו אותו ב־settings.yml או קבלו את אובדן התוצאות ממנו. אלה אינן שתי האפשרויות היחידות, משום שלחלק מחסימות ה־CAPTCHA יש פתרון שנשמר גם לאחר אתחול: לחלק מחסימות ה־CAPTCHA יש פתרון שנשמר גם לאחר אתחול. המנועים הנותרים עדיין משיבים. שגיאת 429 היא המקרה המעורפל, משום שהיא יכולה לנבוע ממגביל הקצב שלכם או ממנוע חיצוני שמסרב לשרת שלכם. לפני שתשנו הגדרות, שורת הלוג מציינת מול איזה משני המצבים אתם מתמודדים.

אם כל המנועים נכשלים בו־זמנית, אין ל־container פתרון שמות יוצא תקין או שאין לו נתיב אל האינטרנט. בדקו זאת מתוך ה־container.

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, וזהו מצב ברירת המחדל, או שה־limiter מופעל וסיווג את הסקריפט שלך כבוט. הוסף תחילה את הפורמט, הפעל מחדש באמצעות docker compose restart core, ולאחר מכן נסה שוב. אם הבקשה עדיין נכשלת, הגדר את limiter: false ובקרת הגישה תתבצע ב־reverse proxy במקום זאת.

האם אני זקוק למכולת Valkey אם ה־limiter כבוי?

השאר אותה פועלת. SearXNG פועל גם בלעדיה, אך אי אפשר להפעיל את ה־limiter מאוחר יותר בלעדיה, והיא גם מאחסנת מצב זמני נוסף. המכולה קטנה ומאחסנת נתונים במטמון בלבד, ולכן הסרתה חוסכת מעט מאוד ומונעת ממך את האפשרות הזו.

כיצד מעדכנים את SearXNG?

הרץ docker compose pull ולאחר מכן docker compose up -d בתוך /opt/searxng. Compose יוצר מחדש כל מכולה שהתמונה שלה השתנתה ומשאיר את תיקיית core-config/ שלך ללא שינוי, ולכן settings.yml נשמר. מכיוון ש־use_default_settings: true ממזג את המפתחות שלך מעל ברירות המחדל שסופקו, אפשרויות שנוספו upstream מתקבלות עם ערכים סבירים במקום לגרום לקובץ להיכשל.

האם כמה אנשים יכולים להשתמש באותו מופע?

כן. זהו המצב שבו מפעילים את ה־limiter ומגדירים את public_instance: true. ההעדפות נשמרות בדפדפן של כל מבקר בנפרד, ולכן אין חשבונות לניהול. נטר את /stats במשך שבוע לאחר פתיחת הגישה, משום שמנועים חיצוניים מתחילים לדחות את השרת שלך זמן רב לפני שתבחין בתוצאות חסרות.