Как установить SearXNG через Docker Compose
Разверните приватный метапоисковик на своем VPS. В статье приведена настройка settings.yml, конфигурация Nginx с TLS и примеры вызова API для ваших скриптов без трекинга.
Что вы создаете
Самостоятельный хостинг SearXNG предоставляет вам приватную поисковую систему, работающую на вашем собственном сервере. SearXNG — это метапоисковая система: она принимает ваш запрос, отправляет его в другие поисковики, такие как Google, Bing, DuckDuckGo и Wikipedia, а затем объединяет полученные данные на одной странице результатов. Профиль пользователя не создается, а файлы cookie для отслеживания не устанавливаются, так как единственная машина, хранящая ваш запрос, — это ваша собственная. Если вы нашли старые руководства для проекта под названием просто Searx, знайте, что это проект, от которого произошел текущий, и в нем не было коммитов с 2023 года, поэтому проверьте состояние обоих проектов, прежде чем следовать какому-либо из них.
Стек технологий невелик. Два контейнера, один файл настроек, один обратный прокси-сервер. Он будет успешно работать на небольшом VPS, что справедливо не для каждого self-hosted сервиса: библиотеки фотографий, сравниваемые в PhotoPrism против Immich, определяют минимальный объем RAM скорее индексатором, чем веб-приложением. Главное решение заключается в том, будет ли ваш экземпляр приватным (доступным только вам и вашим скриптам) или публичным (доступным для любого пользователя в интернете). Этот выбор влияет на настройки безопасности, поэтому примите его до начала ввода команд. По умолчанию рекомендуется приватный вариант.
Существует и вторая причина для запуска такого сервиса. Экземпляр 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=8080SEARXNG_HOST=127.0.0.1 — важный параметр. Он меняет опубликованный порт на 127.0.0.1:8080:8080 вместо [::]:8080:8080, чтобы контейнер отвечал только на адресе loopback, и интернет не мог получить к нему прямой доступ. Пропустите этот шаг, и контейнер окажется доступен сразу после запуска, так как опубликованный порт Docker вставляется перед правилами вашего файрвола. Эту ловушку стоит изучить полностью: опубликованные порты Docker обходят ufw.
SEARXNG_VERSION=latest подходит для обучения. На сервере, который вы планируете использовать постоянно, зафиксируйте тег. По состоянию на июль 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
- jsonsecret_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: контейнер работает от имени собственного непривилегированного пользователя, и если файл будет недоступен для чтения, 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 (transport layer security). Создайте файл /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.comnginx -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-адресу или частной сети и разрешайте доступ только своим хостам. Затем выполняйте запросы умеренно. SearXNG пересылает ваш запрос реальным поисковым системам, поэтому скрипт, выполняющий сотни запросов в секунду, заставит Google заблокировать ваш сервер.
Ограничитель и изменения для публичного экземпляра
Ограничитель — это механизм защиты SearXNG от ботов. Он отслеживает заголовки запросов, IP-адреса и частоту обращений, отбрасывая трафик, который выглядит как автоматизированный. Для хранения этого состояния требуется Valkey, поэтому он включен в файл Compose.
Для частного экземпляра оставьте limiter: false. Ваши собственные скрипты по определению являются автоматизированным трафиком, поэтому ограничитель будет блокировать именно те JSON-запросы, ради которых вы и создавали экземпляр. Контроль доступа в этом случае должен выполнять reverse proxy: пара 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 = truelink_token = true заставляет SearXNG выдавать токен, который может получить только реальный сеанс браузера, что останавливает большинство простых парсеров. Будьте готовы к тому, что публичный экземпляр привлечет их в течение нескольких дней. Ожидайте также ошибок от поисковых движков, так как чем больше трафика вы пересылаете, тем быстрее внешние сервисы начнут возвращать CAPTCHA на адрес вашего сервера. Публичный экземпляр SearXNG требует постоянного обслуживания. Частный экземпляр — нет, поэтому он входит в большинство кратких списков проектов, которые стоит хостить самостоятельно в 2026 году. Не каждый пункт в этих списках является инфраструктурой: превращение библиотеки Jellyfin в интерактивный видеопрокат в стиле 90-х — это тот же самый контейнер за тем же блоком 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, что является состоянием по умолчанию, либо включен ограничитель (limiter), который классифицировал ваш скрипт как бота. Добавьте формат, перезапустите сервис с помощью 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, так как поисковые системы могут начать блокировать ваш сервер задолго до того, как вы заметите отсутствие результатов поиска.