Альтернативи Firecrawl для VPS із self-hosting
Порівнюємо 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 реліз 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. Проєкт не постачає container image і не запускає browser.
Firecrawl self-hosted — це engine, на якому працює hosted product, ліцензований за AGPL-3.0. Його docker-compose.yaml визначає сім services: playwright-service, api, redis, rabbitmq, nuq-postgres, foundationdb і foundationdb-init. Ви отримуєте повноцінну crawl queue, але маєте запускати невелику distributed system.
Hound розміщено в репозиторії master-fetch. До PyPI він постачається як hound-mcp, ліцензований за MIT; станом на 3 August 2026 актуальна версія — 13.0.1. Для роботи потрібен Python 3.11 або новіший. Насамперед це MCP server, а вже потім fetcher: він спочатку використовує звичайний HTTP, а Patchright browser запускає лише тоді, коли звичайний fetch повертає блокування.
Trawl згадано тут, оскільки під час пошуку інших проєктів користувачі стикаються і з ним, але він виконує інше завдання. Він розв’язує JavaScript challenges і CAPTCHAs за допомогою Firefox зі зміненим fingerprint, замінюючи FlareSolverr у media stack на *arr. Це не markdown extractor. У розділі нижче про етичні правила пояснено, чому ця відмінність визначає, чи варто взагалі додавати його до agent stack.
Чому пул браузерів стає причиною відмови невеликих VPS
Кожна відкрита вкладка браузера — це окремий процес renderer із власним DOM (document object model) і власною JavaScript heap. Тому споживання пам’яті залежить від кількості сторінок, відкритих одночасно, а не від кількості сторінок, завантажених за день. У двох цих проєктах такі витрати вказано у власних compose-файлах.
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 для одного контейнера, що містить вбудований Chromium, встановлено 3 GB. Це верхні межі, які вибрали самі проєкти. Це опубліковані значення, а не вимірювання спокійної системи. 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 зберігає там буфери renderer, тому на великих сторінках він аварійно завершує роботу. Обидва browser stack збільшують цей обсяг: у compose-файлі Hound є shm_size: "1gb". Додавайте цей рядок до будь-якого image, який створюєте навколо 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-адрес хмарного сервісу, а кінцеві точки /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.targetsudo 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 без автентифікації — це відкритий проксі. Будь-хто, хто має доступ до порту, може змусити ваш сервер робити запити до будь-якого URL із вашої IP-адреси. Скарга про зловживання надійде вашому провайдеру, а не порушнику. Задокументовані прапорці serve Draco не містять API key, тому захист має забезпечувати мережа. Залишайте прив’язку за замовчуванням 127.0.0.1, якщо агент працює на тому самому сервері. Якщо агент працює на іншому сервері, з’єднайте обидві сторони через приватний тунель. Зазвичай для цього використовують WireGuard VPN, розгорнутий власноруч, і прив’язують сервіс до адреси тунелю, а не до 0.0.0.0. Потім з іншої машини перевірте, що публічна IP-адреса не відповідає. У основах налаштування ufw firewall і облікових записах користувачів із мінімальними привілеями описано обидві частини цього захисту.
Чи зміниться код вашого агента? Сумісність API на практиці
Draco відповідає на маршрути Firecrawl v1: /v1/scrape, /v1/map, /v1/crawl, /v1/batch/scrape і /v1/search, а в його README зазначено, що невідомі поля приймаються та ігноруються. Агент, який уже надсилає запити до /v1/scrape, потребує лише нової базової URL-адреси. Зверніть увагу на зміни з іншого боку: на власній сторінці self-hosting Firecrawl тепер виконує перевірку за допомогою /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-з’єднання й рідко сповільнює роботу загалом, оскільки сайт, який починає застосовувати rate limiting, забирає більше часу, ніж дає економія від вищої паралельності. Кешуйте отримані дані, щоб повторний запуск агента не створював додаткового навантаження на джерело. Це також найдешевша стаття витрат у контролюванні вартості AI-агента для вас.
Механізми challenge wall — окрема тема, і Trawl створено саме для роботи з Cloudflare Turnstile, reCAPTCHA, hCaptcha та GeeTest. Challenge wall — це пряме блокування сайтом автоматизованого трафіку. Обхід такого блокування суперечить умовам використання сайту, а в деяких юрисдикціях може також порушувати закон, тому цей посібник охоплює лише інфраструктуру отримання даних і на цьому зупиняється. Ті самі методи, які дають змогу пройти challenge wall, власники сайтів відстежують і блокують. Тому побудований на них конвеєр буде не лише недоречним, а й нестабільним. Якщо джерело настільки важливе, знайдіть його RSS-стрічку, публічний API або bulk export. Кожен із цих варіантів дешевший в експлуатації, і жоден не перестане працювати через зміну challenge wall.
Підключення агента через 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-браузер, щоб отримувати сторінки для AI-агента?
Для більшості сторінок — ні. Документація, блоги та новинні статті, які формуються на сервері, повністю надходять після звичайного HTTP-запиту та перетворення HTML на Markdown. Саме так Draco працює на нижчих тарифах — приблизно 300 мс на сторінку без браузера, згідно з даними проєкту. Браузер потрібен для застосунків, які формують вміст на клієнті, коли отриманий HTML є порожньою оболонкою. Ізолят V8 у 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 OOM killer видаляє контейнери під навантаженням. Першою ознакою є перезапущений контейнер у docker compose ps без корисних повідомлень у журналі застосунку. Підтвердьте це за допомогою dmesg -T | tail.
Чи є Draco повною заміною Firecrawl API без додаткових змін?
Для кінцевих точок v1 він близький до повної заміни. Він підтримує /v1/scrape, /v1/map, /v1/crawl, /v1/batch/scrape і /v1/search та ігнорує невідомі поля запиту. Тому клієнту, написаному для Firecrawl v1, зазвичай достатньо змінити базову URL-адресу. Це не hosted-продукт: за ним немає керованого пулу проксі, а нові маршрути Firecrawl v2 не входять до його API. Спочатку перевірте кожен виклик, який виконує ваш агент, за допомогою curl.
Чи означає self-hosting скрапера, що можна ігнорувати robots.txt?
Ні. Те, де виконується код, не змінює того, що опублікував сайт і що дозволяють його умови використання. Draco і Firecrawl за замовчуванням дотримуються robots.txt. Прапорець override призначений для сайтів, якими ви володієте, або для яких маєте письмовий дозвіл на сканування. Обмеження частоти запитів усе одно застосовуються на стороні сайту. Тому ввічливий --delay з низькою паралельністю допомагає зберегти доступність вашої IP-адреси. Стек, який працює лише завдяки обходу challenge wall, може припинити роботу без попередження.