- Background agent runner = n8n schedule + Playwright headless + Claude API, chạy 24/7 trên VPS.
- VPS 4GB Ubuntu đủ chạy 5-10 workflow agent đồng thời, mỗi cái scrape + AI parse.
- Use case: monitor giá VPS competitor, track ranking SEO, scrape job listing, daily SaaS metric.
- Setup 40 phút: n8n Docker + Playwright container + Claude credential + workflow JSON.
- Cost: VPS ~350k + Claude API ~10-30$/tháng. Rẻ hơn SaaS scraping tool (49-299$/tháng).
Background agent là mô hình quan trọng cho dev VN 2026: máy chạy 24/7 trên VPS, scrape data, gọi AI parse, alert kết quả qua Telegram/Slack. Khác hẳn workflow tay (chạy khi cần), background agent chủ động làm việc liên tục. Stack tiêu biểu: n8n schedule + Playwright headless browser + Claude API.
Bài này hướng dẫn build background agent runner từ A-Z trên VPS Ubuntu, kèm 5 use case thực tế đã chạy production: monitor giá competitor, track SEO ranking Google, scrape job listing tuyển dụng, daily metric SaaS, news summary tự động.
Mục tiêu cuối bài: bạn có VPS chạy n8n + Playwright Docker, workflow đầu tiên scrape + AI parse, kết quả push Telegram bot mỗi 30 phút. Setup 40-60 phút.
1. Vì sao tự build thay vì dùng SaaS?
| Tool | Pricing | Limit | Tùy biến |
|---|---|---|---|
| Apify (SaaS scrape) | 49-499$/tháng | Tier-based unit | Hạn chế |
| Browse AI | 19-99$/tháng | 200-2000 task/tháng | Limited script |
| ScrapingBee API | 49-249$/tháng | 150k-3M call | Headless only |
| Self-host n8n+Playwright | ~350k VPS | Không (CPU bound) | Full code |
Self-host tiết kiệm 80-90% chi phí, tùy biến full Playwright script (anti-bot, cookie, proxy). Trade-off: tự maintain VPS, fix khi site đích đổi HTML structure.
2. Yêu cầu VPS
- RAM: 4GB tối thiểu (n8n 500MB + Playwright Chromium 800MB-1.5GB peak).
- vCPU: 2-4.
- SSD: 40GB (Chromium installed ~500MB, screenshot/PDF cache).
- Ubuntu 24.04, Docker.
- Network: tốt nhất 200Mbps trong nước (TND) cho scrape Vietnamese sites.
3. Setup n8n + Playwright Docker
# Cài Docker
curl -fsSL https://get.docker.com | sh
mkdir -p /opt/agent-runner/{n8n,playwright}
cd /opt/agent-runner# docker-compose.yml
services:
postgres:
image: postgres:16-alpine
restart: unless-stopped
environment:
POSTGRES_DB: n8n
POSTGRES_USER: n8n
POSTGRES_PASSWORD: $POSTGRES_PASSWORD
volumes:
- ./pgdata:/var/lib/postgresql/data
n8n:
image: n8nio/n8n:latest
restart: unless-stopped
depends_on: [postgres]
environment:
DB_TYPE: postgresdb
DB_POSTGRESDB_HOST: postgres
DB_POSTGRESDB_USER: n8n
DB_POSTGRESDB_PASSWORD: $POSTGRES_PASSWORD
DB_POSTGRESDB_DATABASE: n8n
N8N_HOST: agent.your-domain.com
WEBHOOK_URL: https://agent.your-domain.com/
N8N_ENCRYPTION_KEY: $N8N_ENCRYPTION_KEY
GENERIC_TIMEZONE: Asia/Ho_Chi_Minh
volumes:
- ./n8n:/home/node/.n8n
playwright:
image: mcr.microsoft.com/playwright:v1.49.0-jammy
restart: unless-stopped
command: npx -y playwright run-server --port 3000
ports:
- "127.0.0.1:3000:3000"
shm_size: 2gb # Chromium cần SHM lớn
caddy:
image: caddy:2-alpine
restart: unless-stopped
ports: ["80:80", "443:443"]
volumes:
- ./Caddyfile:/etc/caddy/Caddyfile
- caddy_data:/data
volumes:
caddy_data:docker compose up -d
docker compose logs -f n8n
# Truy cập https://agent.your-domain.com, setup owner4. Workflow đầu tiên: scrape giá VPS competitor
- Trigger: Schedule node, cron 0 9 * * * (9h sáng mỗi ngày).
- Node Code (JavaScript): script Playwright connect tới playwright server :3000, mở page competitor, parse giá theo CSS selector.
- Node Anthropic: prompt "Phân tích giá VPS này so với thị trường, đánh giá deal hay không, output JSON {price, deal_rating, note}".
- Node Postgres: insert vào table competitor_prices.
- Node Telegram: gửi message với summary kèm link.
// Code node Playwright
const { chromium } = require('playwright-core');
const browser = await chromium.connect('ws://playwright:3000');
const context = await browser.newContext({
userAgent: 'Mozilla/5.0 (X11; Linux x86_64) Chrome/120.0.0.0 Safari/537.36'
});
const page = await context.newPage();
await page.goto('https://competitor.example.com/pricing');
await page.waitForSelector('.price-card');
const prices = await page.$$eval('.price-card', cards =>
cards.map(c => ({
name: c.querySelector('.plan-name')?.innerText,
price: c.querySelector('.price')?.innerText,
specs: c.querySelector('.specs')?.innerText
}))
);
await browser.close();
return prices.map(p => ({ json: p }));5. Workflow 2: track SEO ranking Google
- Trigger: cron 0 6 * * * (6h sáng).
- Iterate qua list 50 keyword (Google Sheets).
- Playwright: search google.com.vn với keyword, scroll 100 result, find URL của bạn.
- Node Code: extract position 1-100, capture screenshot top 10.
- Node Postgres: lưu position history.
- Node Claude: tóm tắt "5 keyword tụt hạng nhất, suggest hành động".
- Node Telegram: alert mỗi sáng.
Tránh ban: dùng proxy rotate (Bright Data, Smartproxy), random user-agent, delay 5-10s giữa request, không quá 100 keyword/giờ.
6. Workflow 3: scrape job listing tuyển dụng
- Trigger: cron 0 8,14,20 * * * (3 lần/ngày).
- Playwright: mở topcv, vietnamworks, itviec, filter "React/Node.js senior".
- Loop qua job mới (so với DB), scrape title, company, salary, link.
- Node Claude: extract "tech stack required, year experience, salary range" từ JD.
- Node Notion: tạo database row.
- Node Telegram: notify khi có salary >40tr.
7. Workflow 4: daily SaaS metric
- Trigger: cron 0 9 * * * (9h sáng).
- Node HTTP: GET Stripe API /v1/charges last 24h.
- Node Postgres: query active subscriber count.
- Node Code: tính MRR, churn rate, daily active user.
- Node Claude: prompt "Viết daily SaaS report 200 từ tiếng Việt với các metric sau, highlight thay đổi đáng chú ý".
- Node Slack: post #metrics channel.
8. Workflow 5: news summary tự động
- Trigger: cron 0 */2 * * * (mỗi 2 giờ).
- Node RSS Feed Read: 10 source tech (HN, Reddit r/programming, dev.to, Vercel blog, Anthropic news).
- Filter: chỉ article mới <2h.
- Playwright: open URL article, extract full text (tránh paywall đơn giản).
- Node Claude: tóm tắt 3 câu tiếng Việt + bullet 3 takeaway.
- Node Telegram channel: post summary kèm link gốc.
9. Anti-detection và proxy
- User agent rotation: dùng faker-js random Chrome version.
- Browser fingerprint: playwright-extra với stealth plugin.
- Proxy: residential proxy (Bright Data 10$/GB) cho site khó như Google, LinkedIn.
- Delay random 2-8s giữa request.
- Captcha: 2captcha API (3$/1000 captcha) khi gặp recaptcha.
- Headless detection: playwright-stealth giấu navigator.webdriver.
10. Resource management trên VPS
- Concurrent browser: max 3-5 instance Chromium đồng thời trên VPS 4GB.
- Browser context isolation: mỗi job tạo context riêng, close sau xong.
- Memory cap: docker run --memory=2g playwright container.
- Cleanup: cron 4h sáng restart playwright container, xoá tmp file.
- Monitor: cAdvisor + Prometheus + Grafana track CPU/RAM mỗi container.
11. Cost optimization
- Claude Haiku 4-mini (~10x rẻ Sonnet) cho task parse JSON đơn giản.
- Claude Sonnet 4.7 cho task summarize/analysis cần quality.
- Prompt caching: 50-80% token saved cho prompt repeat (system message).
- Batch processing: gom 10 article -> 1 prompt thay vì 10 prompt riêng.
- Reject low-value scrape: nếu HTML content <500 char, không gửi Claude (chắc chắn lỗi).
12. Error handling và alerting
- n8n có "Error Workflow": fail trigger workflow phụ alert Telegram.
- Retry logic: workflow node có Retry On Failure (3 lần, delay 30s).
- Detect HTML change: cảnh báo khi selector return 0 element (site đổi structure).
- Rate limit: catch 429, exponential backoff.
- Quota alert: log token usage Claude, alert khi vượt 80% budget tháng.
VPS 4GB chạy background agent n8n + Playwright + Claude 24/7
Cloud VPS TND Ubuntu 24.04, SSD CEPH NVMe, snapshot 1-click, backup hằng ngày, network 200Mbps trong nước. Đủ resource cho Chromium concurrent + n8n queue mode + Postgres data, latency thấp tới Anthropic cho stream nhanh.
Xem 8 cấu hình Cloud VPS →FAQ
Playwright vs Puppeteer cho scraping?
Playwright 2026 thắng tuyệt đối: API hiện đại hơn, auto-wait built-in, hỗ trợ Chromium + Firefox + WebKit (test cross-browser), maintained tốt bởi Microsoft. Puppeteer chỉ Chromium, fallback nếu codebase cũ. Cho project mới: chọn Playwright.
Scrape Google search có hợp pháp không?
Vùng xám pháp lý. Google ToS cấm scraping, nhưng dữ liệu công khai trên SERP không phải secret. Risk thực tế: IP bị ban (tạm hoặc vĩnh viễn), captcha xuất hiện liên tục. Mẹo giảm risk: proxy rotation, delay lớn, hạn chế <100 query/ngày từ 1 IP. Production scale: dùng API Serper.dev (~5$/1000 query) thay vì scrape trực tiếp.
n8n có thay thế hoàn toàn được không cần code Python?
Có cho 80% workflow scraping cơ bản. Phức tạp hơn (multi-page navigation, session login, file download) cần Code node JavaScript trong n8n hoặc external Python script. n8n + JS code đủ cho 95% case. Python lợi thế khi cần thư viện ML/data (pandas, numpy).
Playwright container có chiếm RAM kinh khủng không?
Khá nặng. Chromium instance idle ~200MB, page complex (gmail, facebook) peak 800MB-1.5GB. VPS 4GB chỉ chạy 2-3 instance đồng thời. VPS 8GB chạy 5-6. Mẹo: tắt image loading, disable JS không cần, dùng playwright route block tracking pixel - giảm 30-50% RAM.
Có cần Captcha solver cho dev VN site?
Hầu hết site VN không có captcha gắt (trừ ngân hàng, e-gov). Site quốc tế (Google, LinkedIn, Cloudflare) hay có. 2captcha hoặc Anti-Captcha 3-5$/1000 captcha. Trade-off: nếu workflow rate <100/ngày, có thể chấp nhận retry manual khi captcha. Trên 1000/ngày, captcha solver bắt buộc.
Cách backup workflow n8n để recover khi VPS chết?
Backup folder /opt/agent-runner/n8n (chứa SQLite/credentials, settings) và pg_dump Postgres n8n DB hằng đêm. Export workflow JSON qua Settings -> Workflows -> Export All định kỳ. Snapshot 1-click VPS TND (giữ 7 ngày) là backup level VM. Triple protection: file backup + DB dump + VM snapshot.



