SSD Nodes Learn 🎉 VPS от $5.50/мес
Руководства Matt ConnorАвтор: Matt Connor

Альтернативы Firecrawl для VPS: Draco, Hound и Firecrawl

Сравните Draco, Hound и self-hosted Firecrawl по RAM, headless browser и совместимости API. Установка v0.20.5 и подключение к агенту через MCP.

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

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

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

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

Draco — один бинарный файл, написанный на Rust и распространяемый по лицензии MIT или Apache-2.0. Релиз v0.20.5 опубликован 16 July 2026. draco scrape <url> выводит markdown в stdout. draco serve запускает daemon, который принимает запросы на 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. Вы получаете полноценную очередь задач crawling, но должны поддерживать небольшую распределённую систему.

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

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

Почему пул браузеров приводит к отказу небольших VPS

Каждая открытая вкладка браузера — отдельный процесс рендеринга со своей DOM (document object model) и собственной кучей 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 GB, а для контейнера Playwright — 4 GB. Для обоих контейнеров также заданы соответствующие лимиты swap. В Compose Hound задано 3 GB для одного контейнера со встроенным Chromium. Это верхние границы, выбранные разработчиками проектов и опубликованные как ориентиры, а не результаты измерений в состоянии простоя. Кроме того, Redis, RabbitMQ, PostgreSQL и FoundationDB потребляют память сверх значений, указанных для Firecrawl.

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

Есть ещё одна особенность браузера, которая может потратить несколько часов на поиск причины. Docker выделяет контейнеру 64 MB shared memory в /dev/shm, а Chromium размещает там буферы рендеринга. Поэтому Chromium завершается на тяжёлых страницах. В обоих браузерных стеках этот объём увеличен: в Compose Hound указано shm_size: "1gb". Добавляйте эту строку в любой образ, который собираете на основе Playwright.

Качество извлечения на страницах с большим объёмом JavaScript

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

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

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

playwright-service Firecrawl управляет настоящим Chromium, поэтому рендерит страницы так же, как браузер. Однако self-hosted-сборка всё равно не является hosted-продуктом: в документации указано, что self-hosted-инстансы не имеют доступа к Fire Engine. Поэтому в них отсутствуют защита от блокировок и ротация IP-адресов облачного сервиса, а endpoints /agent и /browser не поддерживаются. Hound специально занимает промежуточное положение. Он получает данные по HTTP и повышает уровень обработки для каждого запроса. Его прогретый браузер закрывается после тайм-аута бездействия, поэтому при отсутствии нагрузки потребление ресурсов почти не отличается от базового.

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

В README описан однострочный установщик. Перед передачей команды в shell изучите, что именно он делает: он устанавливает программу в $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 нужен не для оформления: структура архива не входит в публичный контракт проекта, а официальный установщик находит бинарный файл тем же способом.

Запускайте daemon от имени отдельной учётной записи, а не пользователя, под которым вы входите в систему. Запишите /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 отвечает сразу после того, как daemon начинает принимать подключения. Connection refused означает, что он не принимает подключения, поэтому изучите journalctl -u draco -n 50. Обычно порт 3002 уже занят другим процессом, поскольку это также порт Firecrawl по умолчанию. Параметр --port позволяет изменить порт у любого из них. Подробнее о unit-файлах: unit-файлы и таймеры systemd.

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

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

Не размещайте fetch daemon в открытом Интернете

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

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

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

Robots.txt, ограничения частоты запросов и допустимый предел

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

Страницы с проверкой — отдельная тема. Trawl предназначен именно для работы с Cloudflare Turnstile, reCAPTCHA, hCaptcha и GeeTest. Такая страница прямо сообщает, что сайт запрещает автоматизированный трафик. Обход этой проверки нарушает условия использования сайта, а в некоторых регионах — и законодательство. Поэтому в этом руководстве рассматривается только инфраструктура получения данных. Методы, которые проходят такую проверку, владельцы сайтов отслеживают и блокируют. Поэтому построенный на них pipeline будет не только нежелательным, но и нестабильным. Если источник настолько важен, найдите его RSS feed, public API или bulk export. Каждый из этих вариантов дешевле в эксплуатации, и ни один не перестанет работать из-за изменения страницы с проверкой.

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

MCP (model context protocol) — это интерфейс, через который агент вызывает инструмент. 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 публикует endpoint по адресу http://127.0.0.1:8765/mcp, доступный через туннель. Варианты транспорта и список доступных компонентов описаны в материале запуск MCP-серверов на VPS.

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

FAQ

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

Для большинства страниц — нет. Документация, блоги и новостные статьи, отрендеренные на сервере, полностью загружаются обычным HTTP-запросом с последующим преобразованием HTML в Markdown. Именно так работает Draco на младших тарифах: по данным проекта, обработка страницы без browser занимает около 300 ms. Browser оправдан для приложений с рендерингом на стороне клиента, где полученный HTML представляет собой пустой каркас. Изолят V8 в Draco покрывает значительную часть таких сценариев без отдельного browser-процесса. Если это невозможно, Draco завершается с кодом 3, needs_browser.

Сколько RAM требуется self-hosted Firecrawl на VPS?

В compose-файле для контейнера api задан лимит в 8 GB, а для контейнера Playwright — 4 GB. Этот же стек запускает Redis, RabbitMQ, PostgreSQL и FoundationDB. Планируйте не менее 8 GB. На сервере с 2 GB kernel out-of-memory killer удаляет контейнеры при нагрузке. Первым признаком обычно становится перезапуск контейнера в docker compose ps без полезных сообщений в application log. Подтвердите это с помощью dmesg -T | tail.

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

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

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

Нет. Место выполнения кода не меняет ни опубликованные сайтом правила, ни условия, установленные владельцем сайта. Draco и Firecrawl по умолчанию соблюдают robots.txt. Флаг переопределения предназначен для сайтов, которыми вы владеете, или для обхода которых у вас есть письменное разрешение. Ограничения частоты запросов в любом случае действуют на стороне сайта. Поэтому корректный --delay с низким уровнем параллелизма помогает сохранить работоспособность вашего IP-адреса. Стек, который работает только за счёт обхода challenge wall, может внезапно перестать работать.

#scraping#firecrawl#ai-agents#self-hosting#markdown