SSD Nodes Learn 8GB RAM — $66/рік
Посібники Matt ConnorВід Matt Connor · Оновлено 2026-08-01

Як розгорнути власний SearXNG на VPS

Запустіть приватний SearXNG на VPS через Docker Compose: налаштуйте settings.yml, limiter, nginx із TLS і JSON API для власних скриптів без ключа.

Що ви створюєте

Власний SearXNG — це приватна пошукова система, яка працює на вашому сервері. SearXNG — це метапошукова система: вона отримує ваш запит, надсилає його до інших систем, зокрема Google, Bing, DuckDuckGo та Wikipedia, а потім об’єднує отримані результати на одній сторінці. Профіль не створюється, а cookie для відстеження не встановлюється, оскільки ваш запит зберігає лише ваш комп’ютер.

Стек невеликий. Два контейнери, один файл налаштувань і один зворотний проксі-сервер. Основне рішення полягає в тому, чи буде екземпляр приватним, тобто доступним лише вам і вашим власним скриптам, чи публічним, тобто доступним для запитів будь-кому в інтернеті. Від цього вибору залежать параметри безпеки, тому визначтеся до початку налаштування. Типовий варіант — приватний екземпляр.

Є ще одна причина запустити власний екземпляр. Екземпляр SearXNG підтримує JSON, тому будь-який написаний вами скрипт або AI-агент отримує власний API пошуку без ключа, оплати за кожен запит і повідомлень про перевищення квоти.

Встановлення 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, тому контейнер відповідає лише на loopback-адресі, і з Інтернету до нього не можна звернутися безпосередньо. Якщо пропустити цей параметр, контейнер стане доступним одразу після запуску, оскільки опублікований порт Docker обробляється раніше за правила вашого firewall. Цю особливість варто розглянути докладніше: опубліковані порти Docker обходять ufw.

SEARXNG_VERSION=latest підходить для навчання. На важливому для вас сервері зафіксуйте tag. Станом на July 2026 release tags використовують дати й мають вигляд 2026.3.25-541c6c3cb, тому deployment оновлюється тоді, коли ви вирішите це зробити, а не тоді, коли зміниться registry.

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, обмеження швидкості не працюватиме, оскільки всередині контейнера core localhost означає цей самий контейнер.

Секрет зберігається у звичайному файлі, тому захистіть каталог, у якому він розташований, а не сам файл. 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 робить його доступним. Також 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

Із json у formats той самий endpoint, який відображає сторінку, повертає структуровані дані.

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 пошуку стягують плату за кожен запит і жорстко обмежують частоту запитів. Локальний екземпляр використовує один контейнер на сервері, за який ви вже платите, а запити не залишають вашу інфраструктуру. Якщо ви підключаєте інструменти до моделі, та сама логіка стосується запуску MCP-серверів на VPS, де інструмент пошуку зазвичай додають першим.

Для використання API діють два правила. Зробіть екземпляр приватним: прив’яжіть API-частину до loopback-адреси або приватної мережі й дозвольте доступ лише власним хостам. Потім надсилайте запити з помірною частотою. SearXNG пересилає ваш запит до реальних пошукових систем, тому сценарій, який виконує сто запитів за секунду, фактично просить Google заблокувати ваш сервер.

Лімітер і зміни для публічного інстансу

Лімітер — це захист SearXNG від ботів. Він відстежує заголовки запитів, адреси та частоту запитів і відкидає трафік, який виглядає автоматизованим. Для зберігання цього стану йому потрібен Valkey, тому Valkey включено до Compose-файлу.

Для приватного інстансу залиште limiter: false. Ваші власні скрипти за визначенням створюють автоматизований трафік, тому лімітер блокуватиме саме ті виклики JSON, для яких ви створили інстанс. Контроль доступу має виконувати зворотний проксі: пара allow і deny у location nginx, HTTP-аутентифікація basic або брандмауер, який дозволяє доступ лише з інших ваших серверів.

Якщо ви публікуєте інстанс для інших користувачів, увімкніть обидва перемикачі.

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 = true

link_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 ok

FAQ

Чи робить SearXNG мої пошукові запити анонімними?

Він приховує вашу особу від пошукових систем, до яких надсилає запити, оскільки вони бачать запити від вашого сервера, а не від браузера. Він не приховує запити від вашого сервера і не приховує ваш сервер від пошукових систем. В екземплярі для одного користувача весь трафік із цієї адреси належить вам, тому сама адреса стає ідентифікатором. Трафік між вашим браузером і екземпляром захищає сертифікат TLS.

Чому запит JSON повертає 403 Forbidden?

Є 2 причини, і обидві пов’язані з конфігурацією. Або json відсутній у списку formats у розділі search: файлу settings.yml, що є типовим станом, або обмежувач увімкнено, і він класифікував ваш скрипт як бота. Спочатку додайте формат, перезапустіть за допомогою docker compose restart core, а потім повторіть запит. Якщо запит і далі завершується помилкою, задайте limiter: false і керуйте доступом на зворотному проксі.

Чи потрібен контейнер 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-пошукові системи починають відхиляти запити вашого сервера задовго до того, як ви помітите відсутні результати.

#searxng#search#privacy#self-hosting#docker