Crawl4AI¶
概述¶
Crawl4AI 係一套開源嘅「AI 友善」爬蟲框架,目標係幫 LLM 同 RAG pipeline 提供乾淨、結構化嘅網頁內容。傳統爬蟲通常只係攞 HTML,Crawl4AI 唔同,佢會自動執行 JavaScript、等待頁面渲染完成,再抽走導航、廣告、側欄等噪音,輸出方便 LLM 直接使用嘅 Markdown、JSON 或 HTML。
喺 benhoweb 嘅基建入面,Crawl4AI 主要係負責「內容抽取」呢一層:由外部網站攞到內容之後,清洗、轉換成適合入 vector database 嘅格式,再畀 RAG 系統做檢索。因為佢行喺內網,對外唔開 port,所以安全性同可控性都比較高。
架構¶
Crawl4AI 喺本機以單一 Docker container 部署,鏡像係 unclecode/crawl4ai:0.9.2,容器名係 crawl4ai。佢內部透過 Playwright driver 控制無頭 Chromium 做「browserless」渲染,唔需要另外開一個 browser service。
主要執行環境:
- 網絡:
cf_network,固定 IPv4172.21.0.59;冇綁定 host port,其他容器用 hostnamecrawl4ai:11235訪問,外部就經 Cloudflare Tunnel。 - 服務層:gunicorn 起 API server,原裝得 1 個 worker,容易令 healthy check flapping;我哋用自訂
supervisord.conf將 worker 增至 4 個。 - 瀏覽器層:每個 worker 對應一個 Playwright driver,預設有 4 個 Chromium 實例。
- 數據層:內置 Redis,放在 tmpfs
/var/lib/redis,用嚟做任務隊列同暫存;容器重啟之後暫存資料會清空,但 crawl 任務本身係無狀態,所以問題唔大。 - LLM 層:Crawl4AI 嘅 LLM extraction 功能並唔係直接打 OpenAI,而係經我哋嘅 LiteLLM proxy。
OPENAI_BASE_URL指向http://litellm:4000/v1,provider 預設係openai/deepseek-first,即係實際行 DeepSeek 模型。
部署¶
部署用 Docker Compose,服務掛喺現成外部網絡 cf_network,並指定固定 IP:
services:
crawl4ai:
image: unclecode/crawl4ai:0.9.2
container_name: crawl4ai
restart: unless-stopped
mem_limit: 2g
shm_size: 1g
networks:
cf_network:
ipv4_address: 172.21.0.59
兩個資源參數特別重要:
mem_limit: 2g:基線記憶體大概係 1.0 至 1.15GB,用嚟行 4 個 gunicorn workers、4 個 Playwright drivers 同 4 個 Chromium;並行 crawl 時,每個 Chromium 有機會再食多 300 至 500MB,所以要預留 buffer。shm_size: 1g:Chromium 渲染時依賴/dev/shm,如果太細會話「crash shutdown」。畀 1GB 係比較穩陣嘅做法。
另外,因為容器行 read_only: true,所以要將 /tmp、/var/lib/redis、/home/appuser/.crawl4ai、/home/appuser/.gunicorn 都 mount 做 tmpfs,先可以正常運行。
配置¶
Crawl4AI 嘅行為主要靠環境變數控制:
CRAWL4AI_API_TOKEN:API 認證 token,由環境注入。REDIS_PASSWORD:內置 Redis 嘅密碼。LLM_PROVIDER:預設openai/deepseek-first,即係經 LiteLLM 行 DeepSeek。OPENAI_API_KEY:呢度其實係 LiteLLM 嘅認證 key,唔係真係 OpenAI key。OPENAI_BASE_URL:固定為http://litellm:4000/v1,將 LLM 請求送去 LiteLLM proxy。LLM_TEMPERATURE:預設0.7。MAX_CONCURRENT_TASKS:預設4,限住同時間執行嘅 crawl 任務,防止 threads 堆爆。
維運與監控¶
健康檢查用 Python 直接打 /health:
test: ["CMD", "python", "-c", "import urllib.request;urllib.request.urlopen('http://127.0.0.1:11235/health',timeout=10)"]
呢度我哋特登將 timeout 由 3 秒放寬到 10 秒,因為 crawl 進行中嘅時候 healthcheck 要排隊,原本 3 秒太短,成日誤判 unhealthy。配合 interval: 60s、retries: 5、start_period: 60s,可以有效減少假警報。
日常監控要留意:
- 用
docker stats crawl4ai睇記憶體走勢,特別係高峰時段。 - Chromium 如果同時爆幾個,記憶體好容易貼近
mem_limit,有機會 OOM。 - 如果成日 OOM,要調低
MAX_CONCURRENT_TASKS,或者畀多啲 memory。 - 容器本身冇對外 port,唔可以靠 port mapping 訪問;排錯要用
docker exec或者經內網其他 service 入去。
常見問題¶
- Healthcheck 成日 unhealthy:最大原因係 gunicorn 得 1 個 worker,crawl 慢慢嗰陣 health request 要排隊。我哋已經改做 4 workers,並放寬 timeout。
- 記憶體爆煲:基線 1.0GB 只係啱啱起步,並行 crawl 時 Chromium 會用多 300 至 500MB each,所以 2GB limit 係「夠但有風險」。要留意
docker stats。 - LLM extraction 冇回應:先檢查 LiteLLM 係咪行緊、
OPENAI_BASE_URL通唔通。因為我哋用deepseek-firstgroup,如果上游 model 慢,Crawl4AI 嘅 LLM extraction 都會等耐啲。 - 想由外面訪問:唔好直接開 host port,應繼續行 Cloudflare Tunnel,或者由
cf_network入面嘅其他服務 proxy 出去。
相關鏈接¶
來源¶
自動生成(2026-08-19 容器覆蓋率補完第二批)