SSD Nodes Learn Hosting plans →
Руководства Matt ConnorАвтор: Matt Connor · Обновлено 2026-08-27

Self-hosted альтернативы Firecrawl для VPS: сравнение

Сравнение Draco, Hound и Firecrawl по потреблению RAM и требованиям к headless-браузеру. Инструкция по установке с фиксацией версий и настройка подключения через MCP.

Что должна делать self-hosted альтернатива Firecrawl

У self-hosted альтернативы Firecrawl одна задача: получить URL и вернуть содержимое страницы в виде чистого markdown, пригодного для чтения агентом. Облачные API взимают плату за каждую страницу, поэтому расходы растут пропорционально любопытству вашего агента, в то время как VPS, за который вы уже платите, может выполнять ту же работу. Проекты различаются по одному вопросу: должен ли на вашем сервере запускаться headless-браузер (реальный движок браузера, работающий без графического интерфейса)?

Ответ на этот вопрос определяет потребление оперативной памяти, стоимость обработки каждой страницы и вероятность того, что страница вернётся пустой. В этом руководстве сравниваются Draco, Hound и self-hosted релиз Firecrawl, выполняется установка наиболее легковесного решения с фиксацией версии, а также его подключение к агенту через MCP (model context protocol).

Четыре проекта и описание каждого из них

Draco — это один исполняемый файл, написанный на Rust, распространяемый по лицензии MIT или Apache-2.0. Релиз v0.20.5 был опубликован 16 июля 2026 года. draco scrape <url> выводит markdown в stdout. draco serve запускает демон, который отвечает на 127.0.0.1:3002 — порту, используемом Firecrawl. Проект не поставляется в виде образа контейнера и не запускает браузер.

Firecrawl self-hosted — это движок, лежащий в основе облачного продукта, распространяемый по лицензии AGPL-3.0. Его docker-compose.yaml определяет семь сервисов: playwright-service, api, redis, rabbitmq, nuq-postgres, foundationdb и foundationdb-init. Вы получаете полноценную очередь обхода (crawl queue), но ценой запуска небольшой распределенной системы.

Hound находится в репозитории master-fetch и публикуется в PyPI как hound-mcp, лицензия MIT, версия 13.0.1 на 3 августа 2026 года. Требуется Python 3.11 или новее. Это в первую очередь MCP-сервер и только во вторую — инструмент для получения данных: он пытается использовать обычный HTTP и запускает браузер Patchright только в том случае, если простой запрос блокируется.

Trawl включен в список, так как пользователи часто находят его при поиске других инструментов, хотя он выполняет иную задачу. Он решает JavaScript-задачи и CAPTCHA с помощью модифицированного Firefox, заменяя FlareSolverr в стеке медиа-приложений *arr. Это не экстрактор markdown. Раздел об этике ниже объясняет, почему это различие определяет, стоит ли вообще включать его в ваш стек агентов.

Почему пул браузеров — это причина гибели слабых VPS

Каждая открытая вкладка браузера — это отдельный процесс рендеринга, который удерживает собственную DOM (объектную модель документа) и кучу JavaScript. Поэтому потребление памяти масштабируется в зависимости от количества страниц, открытых в один момент времени, а не от количества страниц, загруженных за день. В двух из этих проектов стоимость ресурсов прописана прямо в их файлах compose.

ChartMemory ceilings each project sets in its own compose file (GB)
The data behind this chart
[
  {
    "label": "Firecrawl api",
    "memory_limit_gb": 8
  },
  {
    "label": "Firecrawl playwright",
    "memory_limit_gb": 4
  },
  {
    "label": "Hound (browser included)",
    "memory_limit_gb": 3
  }
]

Файл compose для Firecrawl ограничивает контейнер api значением 8 ГБ, а контейнер Playwright — 4 ГБ, с соответствующими лимитами swap. Файл compose для Hound устанавливает 3 ГБ для одного контейнера, в который встроен Chromium. Это потолки, выбранные самими проектами; это опубликованные цифры, а не замеры системы в состоянии покоя. Кроме того, Redis, RabbitMQ, PostgreSQL и FoundationDB также требуют свою долю ресурсов сверх цифр Firecrawl.

Потолок, установленный выше объема имеющейся у вас оперативной памяти, бесполезен. Когда память на сервере заканчивается, механизм out-of-memory killer ядра завершает процесс, поэтому контейнер исчезает из docker compose ps без записи какой-либо ошибки в лог приложения. Читайте dmesg -T | tail после любого перезапуска, причину которого вы не можете объяснить. Закладывайте 8 ГБ для полного стека Firecrawl и считайте 4 ГБ минимальным порогом для тестового сервера. Настройка лимитов для каждого сервиса описана в ограничениях памяти в Docker Compose.

Еще одна деталь, связанная с браузерами, стоит многим потраченного вечера. Docker предоставляет контейнеру 64 МБ разделяемой памяти в /dev/shm, а Chromium размещает там буферы рендеринга, из-за чего он аварийно завершается на «тяжелых» страницах. Оба стека браузеров увеличивают этот объем: в compose для Hound присутствует shm_size: "1gb". Скопируйте эту строку в любой образ, который вы строите на базе Playwright.

Качество извлечения данных на страницах с активным использованием JavaScript

Для статического HTML, блогов с серверным рендерингом, страниц документации или новостных статей результат практически идентичен, и побеждает тот, кто работает быстрее. Разница проявляется на страницах с клиентским рендерингом, где полученный HTML представляет собой пустую оболочку, а текст подгружается через JavaScript после загрузки.

Draco использует многоуровневую систему обработки. Уровни Tier 0 и Tier 1 анализируют HTML без использования JavaScript. Уровень Tier 2 запускает собственный JavaScript страницы внутри изолированного процесса V8 — это движок JavaScript без полноценного браузера. В README указано, что код страницы не получает там доступа к возможностям хоста. Это позволяет обрабатывать многие одностраничные приложения (SPA), потребляя значительно меньше памяти, чем полноценный браузер. Когда Draco сталкивается с непреодолимым препятствием, draco scrape завершается с кодом 3, needs_browser. Проверяйте это в своих скриптах, так как пустой файл с нулевым кодом завершения — это ошибка, которая незаметно отравляет контекст агента:

draco scrape https://example.com > page.md
echo "exit=$?"

Сервис playwright-service от Firecrawl управляет реальным Chromium, поэтому он отрисовывает страницу так же, как это делает браузер. Самостоятельно развернутая сборка — это не то же самое, что облачный продукт: в документации указано, что у локальных экземпляров нет доступа к Fire Engine, поэтому функции обхода блокировок и ротации IP-адресов облачного сервиса отсутствуют, а эндпоинты /agent и /browser не поддерживаются. Hound намеренно занимает промежуточное положение. Он выполняет запросы по HTTP и повышает уровень обработки по мере необходимости, а его «разогретый» браузер закрывается по истечении тайм-аута простоя, поэтому неактивная система остается в состоянии, близком к базовому потреблению ресурсов.

Установка Draco с фиксацией версии

В README описан установщик в одну строку. Изучите его содержимое перед передачей в оболочку: он устанавливает файлы в $HOME/.draco/bin/draco, всегда загружает релиз latest и не проверяет подписи или хеш-суммы. На сервере фиксируйте версию и проверяйте загруженные файлы.

cd /tmp
curl -fsSLO https://github.com/0xchasercat/draco/releases/download/v0.20.5/draco-linux-x86-64.tar.gz
curl -fsSLO https://github.com/0xchasercat/draco/releases/download/v0.20.5/SHA256SUMS
sha256sum --ignore-missing -c SHA256SUMS

Эта команда выводит draco-linux-x86-64.tar.gz: OK. Строка FAILED означает, что полученные байты не совпадают с опубликованными проектом, поэтому удалите их и повторите процесс.

mkdir -p draco-v0.20.5
tar -xzf draco-linux-x86-64.tar.gz -C draco-v0.20.5
sudo install -m 755 "$(find draco-v0.20.5 -type f -name draco | head -n1)" /usr/local/bin/draco
draco scrape https://example.com

Последняя команда выводит страницу с примером в формате markdown менее чем за секунду. Путь find — это не декорация: структура архива не является частью публичного контракта проекта, и официальный установщик находит бинарный файл именно таким способом.

Запускайте демон от имени отдельной учетной записи, а не от вашего пользователя. Создайте /etc/systemd/system/draco.service:

[Unit]
Description=Draco fetch daemon
After=network-online.target
Wants=network-online.target

[Service]
User=draco
ExecStart=/usr/local/bin/draco serve --host 127.0.0.1 --port 3002 --max-concurrency 4
Restart=on-failure
NoNewPrivileges=true
ProtectSystem=strict
ProtectHome=true
PrivateTmp=true

[Install]
WantedBy=multi-user.target
sudo useradd --system --no-create-home --shell /usr/sbin/nologin draco
sudo systemctl daemon-reload
sudo systemctl enable --now draco
curl -s http://127.0.0.1:3002/health

/health отвечает сразу, как только демон начинает прослушивание порта. Ошибка Connection refused означает, что порт не прослушивается, поэтому изучите journalctl -u draco -n 50. Частая причина — другой процесс уже занял порт 3002, так как это порт по умолчанию для Firecrawl, и --port позволяет изменить его для любого из них. Подробнее о файлах юнитов: юниты сервисов и таймеры systemd.

Теперь выполните запрос так, как это будет делать ваш агент:

curl -X POST http://127.0.0.1:3002/v1/scrape \
  -H 'content-type: application/json' \
  -d '{"url": "https://example.com", "formats": ["markdown"]}'

Ограничение доступа к fetch-демону из публичной сети

API для получения данных без аутентификации является открытым прокси-сервером. Любой, кто имеет доступ к порту, может заставить ваш сервер отправить запрос по любому URL с вашего IP-адреса, и жалобы на злоупотребления поступят вашему провайдеру, а не злоумышленнику. Документированные флаги serve Draco не включают API-ключ, поэтому защита должна обеспечиваться на сетевом уровне. Оставьте привязку к 127.0.0.1 по умолчанию, если агент работает на той же машине. Если агент находится в другом месте, соедините обе стороны через приватный туннель; собственный WireGuard VPN — стандартное решение. Выполняйте привязку к адресу туннеля, а не к 0.0.0.0. Затем проверьте с другой машины, что публичный IP не отвечает на запросы. Основы работы с ufw и использование учетных записей с минимальными привилегиями охватывают обе стороны этой задачи.

Изменится ли код вашего агента? Совместимость API на практике

Draco поддерживает маршруты Firecrawl v1: /v1/scrape, /v1/map, /v1/crawl, /v1/batch/scrape и /v1/search, а в его README указано, что неизвестные поля принимаются и игнорируются. Агенту, который уже отправляет запросы на /v1/scrape, требуется только новый базовый URL. Следите за изменениями на стороне сервера: страница самостоятельного хостинга Firecrawl теперь использует для тестирования /v2/crawl, а текущие SDK работают с v2. Поэтому клиент v2, направленный на Draco, запрашивает маршрут, который Draco не публикует. Проверяйте каждый вызов с помощью curl перед внесением правок в код агента и анализируйте тело JSON, а не код состояния, так как именно в именах полей эти реализации расходятся.

Robots.txt, ограничения частоты запросов и этика использования

Draco по умолчанию считывает robots.txt, а --ignore-robots отключает эту функцию. В документации Firecrawl указано такое же поведение по умолчанию. Оставьте оба параметра без изменений. Затем установите собственный темп: --delay задает задержку в миллисекундах между запросами, а --max-concurrency ограничивает количество параллельных задач (значение по умолчанию для демона — 8). Значение от 2 до 4 более щадящее для общего канала VPS и редко замедляет работу в целом, так как сайт, начавший ограничивать частоту ваших запросов, потребует больше времени на ожидание, чем вы сэкономите за счет параллелизма. Кэшируйте полученные данные, чтобы повторный запуск агента не создавал нагрузки на источник. Это также самая дешевая статья расходов в контроле затрат на работу AI-агента.

Стены защиты от ботов (challenge walls) — отдельная тема, и Trawl создан именно для них: Cloudflare Turnstile, reCAPTCHA, hCaptcha и GeeTest. Стена защиты — это прямой отказ сайта принимать автоматизированный трафик. Попытки обойти её нарушают условия использования сайта, а в некоторых юрисдикциях — и закон, поэтому данное руководство ограничивается описанием инфраструктуры для получения данных. Те же методы, которые позволяют пройти защиту, отслеживаются и блокируются владельцами сайтов, что делает любой построенный на них конвейер хрупким и некорректным. Если источник данных действительно важен, ищите его RSS-ленту, публичный API или возможность массовой выгрузки. Каждый из этих способов дешевле в эксплуатации и не сломается в тот же день, когда на сайте обновят систему защиты.

Подключение к агенту через MCP

MCP (model context protocol) — это интерфейс, через который агент вызывает инструмент. Какие инструменты вообще доступны модели и может ли она вызывать их без предварительного запроса к вам, определяется уровнем выше — обвязкой, внутри которой работает модель. Поэтому запустить daemon в режиме прослушивания — только половина настройки. Draco содержит MCP-сервер в том же бинарном файле и работает через stdio:

{ "mcpServers": { "draco": { "command": "draco", "args": ["mcp"] } } }

Инструменты становятся доступны агенту как draco_scrape, draco_search и набор draco_interact_*. Stdio работает только в том случае, если процесс агента и бинарный файл находятся на одной машине, так как транспорт использует стандартный ввод этого процесса. Для агента на другом хосте Hound предоставляет MCP через HTTP: hound --http --host 127.0.0.1 --port 8765 публикует эндпоинт по адресу http://127.0.0.1:8765/mcp, к которому можно обратиться через туннель. Выбор транспорта и настройки доступа описаны в разделе запуск MCP-серверов на VPS.

Получение пар через поиск. Агент, который умеет только выполнять запросы, ожидает, что вы предоставите URL. Добавьте собственный экземпляр SearXNG, и он сможет находить их самостоятельно — это работает так же, как навык поиска в браузере на базе SearXNG. После запуска демона он становится общим сервисом для любого из самостоятельно развернутых AI-агентов. Если вы не уверены в работе агентской части, написание небольшого цикла агента вручную поможет понять, куда подключается инструмент получения данных и как модель обрабатывает полученный markdown.

FAQ

Нужен ли headless-браузер для получения страниц для AI-агента?

Для большинства страниц — нет. Документация, блоги и новостные статьи, отрендеренные на сервере, приходят в полном объеме при обычном HTTP-запросе с последующим преобразованием HTML в markdown. Именно так работает Draco на базовых уровнях, затрачивая около 300 мс на страницу без использования браузера, согласно данным самого проекта. Браузер потребляет ресурсы памяти при работе с приложениями, отрендеренными на стороне клиента, где полученный HTML является пустой оболочкой. Изолят V8 в Draco покрывает большую часть таких случаев без запуска процесса браузера, а при невозможности обработки завершается с кодом 3, needs_browser.

Сколько оперативной памяти нужно для self-hosted Firecrawl на VPS?

В файле compose установлен лимит 8 ГБ для контейнера api и 4 ГБ для контейнера Playwright; этот же стек запускает Redis, RabbitMQ, PostgreSQL и FoundationDB. Планируйте использование 8 ГБ. На сервере с 2 ГБ памяти OOM-killer ядра принудительно завершает контейнеры под нагрузкой. Первым признаком этого является перезапуск контейнера в docker compose ps при отсутствии полезной информации в логах приложения; подтвердите это с помощью dmesg -T | tail.

Является ли Draco прямой заменой API Firecrawl?

Для эндпоинтов v1 — почти. Он поддерживает /v1/scrape, /v1/map, /v1/crawl, /v1/batch/scrape и /v1/search и игнорирует неизвестные поля запроса, поэтому клиенту, написанному для Firecrawl v1, обычно достаточно сменить только базовый URL. Это не облачный продукт: за ним нет пула управляемых прокси, а новые маршруты v2 из Firecrawl не реализованы. Сначала проверяйте каждый вызов вашего агента с помощью curl.

Означает ли self-hosting скрапера, что можно игнорировать robots.txt?

Нет. Место запуска кода не меняет того, что опубликовал сайт или что разрешают его правила использования. И Draco, и Firecrawl по умолчанию соблюдают robots.txt, а флаг переопределения существует для сайтов, которыми вы владеете или на сканирование которых у вас есть письменное разрешение. Ограничения частоты запросов (rate limits) в любом случае применяются на стороне сервера, поэтому вежливый --delay с низкой параллельностью позволит вашему IP-адресу оставаться в рабочем состоянии. Стек, который работает только за счет обхода защиты, — это стек, который перестанет работать без предупреждения.