SSD Nodes Learn Hosting plans →
Руководства Matt ConnorАвтор: Matt Connor

Как запустить свой SearXNG через Docker Compose

Разверните приватный поисковик SearXNG на собственном VPS. В руководстве описана настройка settings.yml, лимиты запросов, конфигурация Nginx с TLS и работа с JSON API.

Что вы создаете

Самостоятельный хостинг SearXNG предоставляет вам частную поисковую систему, работающую на вашем собственном сервере. SearXNG — это метапоисковая система: она принимает ваш запрос, отправляет его в другие поисковики, такие как Google, Bing, DuckDuckGo и Wikipedia, а затем объединяет полученные результаты на одной странице. Профиль пользователя не создается, файлы cookie для отслеживания не устанавливаются, так как единственный компьютер, хранящий ваш запрос, — это ваш собственный. Если вы нашли старые руководства для проекта под названием Searx, знайте, что именно от него произошел текущий проект. Он не поддерживается с сентября 2023 года, когда в репозитории было объявлено о прекращении поддержки Searx, и единственный коммит с тех пор — примечание в документации от мая 2026 года — ничего не изменил. Поэтому проверьте состояние обоих проектов, прежде чем следовать какому-либо из них.

Стек технологий невелик. Два контейнера, один файл настроек, один обратный прокси-сервер. Он будет комфортно работать на небольшом VPS, что нельзя сказать о каждом self-hosted сервисе: библиотеки фотографий, рассмотренные в сравнении PhotoPrism и Immich, определяют минимальный объем оперативной памяти исходя из требований индексатора, а не веб-приложения. Главное решение — будет ли ваш экземпляр частным (доступным только вам и вашим скриптам) или публичным (доступным любому пользователю в интернете). Этот выбор влияет на настройки безопасности, поэтому примите его до начала работы. По умолчанию рекомендуется вариант «частный».

Есть и вторая причина для запуска такого сервиса. Экземпляр SearXNG поддерживает формат JSON, поэтому любой ваш скрипт или агент ИИ получает собственный поисковый 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, который Docker публикует на всех адресах. Благодаря этому контейнер отвечает только на loopback-адресе, и интернет не может получить к нему прямой доступ. Пропустите этот шаг, и контейнер окажется доступен сразу после запуска, так как опубликованный порт Docker вставляется в правила брандмауэра до ваших собственных правил. Эту ловушку стоит изучить полностью: опубликованные порты Docker обходят ufw.

SEARXNG_VERSION=latest подходит для обучения. На сервере, который вы используете для работы, зафиксируйте тег. По состоянию на октябрь 2026 года теги релизов основаны на датах и выглядят как 2026.10.4-d48c4b555, поэтому зафиксированное развертывание обновляется тогда, когда вы решите, а не когда меняется реестр. Такая же дисциплина полезна для любого другого долгоживущего сервиса на сервере, поэтому self-hosted ретранслятор 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 перенаправляет миниатюры результатов через ваш сервер, чтобы сайты, на которых размещены изображения, не видели IP-адреса ваших посетителей.

В valkey.url используется имя хоста valkey, так как это имя сервиса в файле Compose. Compose помещает оба контейнера в одну сеть, где имена сервисов разрешаются корректно. Если указать localhost, ограничитель работать не будет, так как внутри контейнера core под localhost понимается сам этот контейнер.

Секретный ключ хранится в обычном текстовом файле, поэтому защитите директорию, в которой он находится. chmod 750 /opt/searxng ограничивает доступ для других пользователей хоста. Вы также можете изменить права доступа к core-config/settings.yml на 600 без каких-либо проблем: точка входа официального контейнера запускается от имени root и, при значении FORCE_OWNERSHIP по умолчанию true, передает права на смонтированную директорию конфигурации пользователю searxng внутри контейнера перед запуском SearXNG. Файл остается доступным для чтения. Побочный эффект заметен на хосте: этот шаг меняет владельца core-config/ на ID пользователя внутри контейнера, поэтому будьте готовы к тому, что для последующего редактирования файла потребуется 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, будет содержать адрес прокси-сервера. В результате ограничитель скорости (rate limiter) будет видеть одного клиента, создающего весь трафик, и не сможет различать посетителей.

Почему скриптам и агентам нужен JSON 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. Этого достаточно для работы суммаризатора, проверки ссылок или исследовательского цикла. Передача этих результатов языковой модели — более сложный шаг, чем кажется, поскольку поисковая выдача представляет собой недоверенный текст, который может содержать собственные инструкции. Именно этот вопрос подробно разбирается в настройке AI-агента для работы с вашим экземпляром SearXNG.

Это важно для любых агентных систем. Языковая модель имеет дату отсечки знаний, поэтому ей нужен поиск в реальном времени для ответов на вопросы о текущих событиях, а коммерческие поисковые API взимают плату за каждый запрос и жестко ограничивают их количество. Локальный экземпляр требует лишь одного контейнера на сервере, за который вы уже платите, и запросы никогда не покидают его пределы. Если вы подключаете инструменты к модели, та же логика применима к запуску MCP-серверов на VPS, где поисковый инструмент обычно добавляется первым.

Два правила использования API. Держите экземпляр приватным: привязывайте API к loopback-адресу или частной сети и разрешайте доступ только своим хостам. Это тот же подход, который требуется для self-hosted трекера местоположения при работе с эндпоинтом, куда ваш телефон отправляет свои координаты. И делайте запросы осторожно. SearXNG пересылает ваш запрос реальным поисковым системам, поэтому скрипт, выполняющий сотни запросов в секунду, вынуждает Google заблокировать ваш сервер.

Ограничитель и изменения для публичного экземпляра

Ограничитель (limiter) — это механизм защиты SearXNG от ботов. Он отслеживает заголовки запросов, IP-адреса и частоту обращений, отбрасывая трафик, который выглядит как автоматизированный. Для хранения этого состояния требуется Valkey, поэтому он включен в файл Compose.

Для частного экземпляра оставьте limiter: false. Ваши собственные скрипты по определению являются автоматизированным трафиком, поэтому ограничитель будет блокировать именно те JSON-запросы, ради которых вы и развернули экземпляр. Вместо этого контроль доступа должен осуществлять обратный прокси: пара allow и deny в location nginx, HTTP basic authentication или межсетевой экран, разрешающий доступ только вашим серверам. Если вам нужно обращаться к частному экземпляру с ноутбука, который перемещается между сетями, использование v3 onion-адреса — это четвертый вариант, так как Tor подключается к тому же порту loopback, не открывая ничего лишнего в интернет.

Если вы публикуете экземпляр для других пользователей, включите оба переключателя.

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 году. Не каждый пункт в этих списках является инфраструктурой: превращение библиотеки Jellyfin в интерактивный видеопрокат в стиле 90-х — это тот же самый контейнер за тем же блоком nginx, ориентированный на вечерний досуг, а не на рабочий процесс.

Почему поиск не выдает результаты

Откройте /stats на вашем экземпляре. Там перечислены все поисковые движки с указанием частоты ошибок и времени отклика; это первое место, куда стоит заглянуть, если результатов поиска стало подозрительно мало.

Движок, помеченный ошибкой "Access denied" или "CAPTCHA", заблокировал IP-адрес вашего сервера. Это часто случается с адресами из диапазонов дата-центров, так как поисковые системы считают их источниками парсинга. В таких случаях 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 (это состояние по умолчанию), либо включен ограничитель, который классифицировал ваш скрипт как бота. Добавьте формат, перезапустите сервис с помощью docker compose restart core и попробуйте снова. Если ошибка сохраняется, установите limiter: false и управляйте доступом на уровне reverse proxy.

Нужен ли контейнер Valkey, если я не использую ограничитель?

Оставьте его запущенным. SearXNG работает и без него, но без него вы не сможете включить ограничитель в будущем, а также в нем хранятся другие временные данные. Контейнер занимает мало места и хранит только кэшированные данные, поэтому его удаление почти не дает экономии ресурсов, но лишает вас гибкости настроек.

Как обновить SearXNG?

Выполните docker compose pull, а затем docker compose up -d в директории /opt/searxng. Docker Compose пересоздает все контейнеры, образы которых изменились, оставляя вашу директорию core-config/ нетронутой, поэтому файл settings.yml сохраняется. Поскольку use_default_settings: true объединяет ваши ключи с настройками по умолчанию, новые опции, добавленные разработчиками, появляются с разумными значениями, не нарушая работу файла.

Могут ли несколько человек пользоваться одним инстансом?

Да, это именно тот случай, когда стоит включить ограничитель и настроить public_instance: true. Настройки хранятся в браузере каждого посетителя, поэтому управлять учетными записями не нужно. В течение недели после открытия доступа следите за /stats, так как поисковые системы могут начать блокировать ваш сервер задолго до того, как вы заметите отсутствие результатов поиска.