Browserless là một công cụ mã nguồn mở (open-source) tuyệt vời cho phép bạn chạy các trình duyệt headless (không giao diện) trong Docker. Nó hoạt động như một máy chủ độc lập, cho phép các ứng dụng Node.js của bạn kết nối và điều khiển trình duyệt thông qua WebSocket hoặc REST API.
Browserless hoạt động bằng cách:
- Lắng nghe các kết nối WebSocket từ các thư viện như Puppeteer hoặc Playwright
- Khởi động Chrome/Chromium và chuyển tiếp yêu cầu của bạn
- Quản lý tự động các tác vụ như tải font, xử lý session, và giải phóng tài nguyên
- Cung cấp REST API cho các tác vụ phổ biến (tạo PDF, chụp ảnh, lấy HTML)
Nói một cách đơn giản, Browserless giống như một dịch vụ web cho trình duyệt – bạn gửi yêu cầu, nó trả lại kết quả.
Lợi ích chính
Browserless mang lại nhiều lợi ích so với việc chạy Puppeteer trực tiếp:
- Tách biệt cơ sở hạ tầng: Trình duyệt chạy riêng biệt, không phụ thuộc vào ứng dụng chính
- Quản lý tài nguyên tốt hơn: Tự động queue các yêu cầu, kiểm soát số lượng session đồng thời
- Hỗ trợ nhiều thư viện: Tương thích với Puppeteer, Playwright, và các thư viện khác
- Dễ deploy: Chỉ cần chạy Docker image, không cần cấu hình phức tạp
- Debugger tích hợp: Công cụ UI để theo dõi và gỡ lỗi các session hiện tại

Tại sao nên sử dụng Browserless
So sánh: Puppeteer trực tiếp vs. Browserless
| Tiêu Chí | Puppeteer Trực Tiếp | Browserless |
|---|---|---|
| Cài đặt | Cần cài Chrome/Puppeteer | Chỉ Docker |
| Quản lý tài nguyên | Manual | Tự động |
| Scaling | Phức tạp | Đơn giản |
| Độc lập | Gắn chặt với app | Hoàn toàn độc lập |
| Debugger | Cơ bản | Nâng cao với UI |
| REST API | Không có | Có sẵn |
Trường hợp sử dụng lý tưởng
Browserless là lựa chọn hoàn hảo cho:
- Web scraping: Lấy dữ liệu từ các trang web có JavaScript
- Kiểm thử tự động: Chạy các test E2E trên các trình duyệt
- Sinh PDF: Chuyển đổi HTML thành PDF với định dạng đẹp
- Chụp ảnh: Tạo screenshot tự động của trang web
- Tự động hóa quy trình: Đăng nhập, điền form, nhấp button tự động
Yêu cầu hệ thống
Trước khi bắt đầu, hãy chắc chắn bạn có:
- Docker cài đặt (phiên bản 19.03 hoặc cao hơn)
- Windows: Docker Desktop
- macOS: Docker Desktop (hỗ trợ Apple Silicon M1/M2)
- Linux: Docker Engine
- Node.js (phiên bản 14 hoặc cao hơn) – để chạy script Puppeteer
- RAM tối thiểu: 2GB (khuyến nghị 4GB trở lên)
- Không gian đĩa: 2-3GB cho Docker image
Kiểm tra xem Docker đã cài chưa bằng:
docker --version
node --versionNếu chưa, có thể xem bài này: Hướng dẫn cài đặt Docker, Docker Compose trên Ubuntu
Cài đặt Browserless
Bước 1: Khởi động Docker Container
Lệnh cơ bản nhất để chạy Browserless:
docker run -p 3000:3000 ghcr.io/browserless/chromiumĐiều này sẽ:
- Tải image
browserless/chromiumtừ GitHub Container Registry - Ánh xạ cổng 3000 bên trong container tới cổng 3000 trên máy host
- Khởi chạy Browserless sẵn sàng nhận yêu cầu
Bước 2: Xác minh cài đặt
Mở trình duyệt và truy cập:
http://localhost:3000/docsBạn sẽ thấy trang OpenAPI với tài liệu API đầy đủ và UI để thử nghiệm các endpoint.
Bước 3: (Tùy chọn) Sử dụng Docker Compose
Để dễ quản lý, tạo file docker-compose.yml:
version: '3.8'
services:
browserless:
image: ghcr.io/browserless/chromium
ports:
- "3000:3000"
environment:
- TIMEOUT=30000
- MAX_CONCURRENT_SESSIONS=5
restart: unless-stoppedSau đó chạy:
docker-compose up -dCấu hình và tùy chỉnh
Browserless có nhiều biến môi trường mà bạn có thể tùy chỉnh:
Các biến môi trường quan trọng
docker run -p 3000:3000 \
-e PORT=3000 \
-e TIMEOUT=30000 \
-e MAX_CONCURRENT_SESSIONS=5 \
-e ENABLE_CORS=true \
-e TOKEN=your-secret-token \
ghcr.io/browserless/chromium| Biến | Mô Tả | Mặc Định |
|---|---|---|
PORT | Cổng nội bộ Browserless | 3000 |
TIMEOUT | Thời gian timeout cho mỗi session (ms) | 30000 |
MAX_CONCURRENT_SESSIONS | Số lượng session đồng thời tối đa | 10 |
ENABLE_CORS | Kích hoạt CORS | true |
TOKEN | Token xác thực API | (không có) |
DEBUG | Bật chế độ debug | false |
Ví dụ: Cấu hình cho Production
docker run -p 8080:3000 \
-e PORT=3000 \
-e TIMEOUT=60000 \
-e MAX_CONCURRENT_SESSIONS=20 \
-e TOKEN=abc123xyz789 \
-e ENABLE_CORS=false \
-m 2g \
--restart always \
ghcr.io/browserless/chromiumGiải thích:
-m 2g: Giới hạn bộ nhớ ở 2GB--restart always: Tự động khởi động lại container nếu bị dừngTOKEN: Yêu cầu xác thực cho tất cả các yêu cầu API- Timeout dài hơn cho các tác vụ phức tạp
Sử dụng với Puppeteer
Bước 1: Thiết lập dự án Node.js
Tạo thư mục mới và khởi tạo Node.js:
mkdir browserless-example
cd browserless-example
npm init -yBước 2: Cài đặt Puppeteer
npm install puppeteerBước 3: Tạo script kết nối tới Browserless
Thay vì chạy Puppeteer cục bộ, chúng ta sẽ kết nối tới Browserless server:
Cách cũ (Puppeteer Cục Bộ):
const puppeteer = require('puppeteer');
const browser = await puppeteer.launch();Cách mới (Với Browserless):
const puppeteer = require('puppeteer');
const browser = await puppeteer.connect({
browserWSEndpoint: 'ws://localhost:3000',
});Đó là tất cả! Chỉ thay đổi một dòng code.
Ví dụ thực tế
Ví dụ 1: Lấy tiêu đề trang web
Tạo file get-title.js:
const puppeteer = require('puppeteer');
async function getTitle() {
const browser = await puppeteer.connect({
browserWSEndpoint: 'ws://localhost:3000',
});
try {
const page = await browser.newPage();
await page.goto('https://example.com', {
waitUntil: 'networkidle2'
});
const title = await page.title();
console.log('Tiêu đề trang:', title);
} catch (error) {
console.error('Lỗi:', error);
}
}
getTitle();Chạy:
node get-title.jsVí dụ 2: Chụp ảnh toàn trang
Tạo file screenshot.js:
const puppeteer = require('puppeteer');
async function takeScreenshot() {
const browser = await puppeteer.connect({
browserWSEndpoint: 'ws://localhost:3000',
});
try {
const page = await browser.newPage();
await page.setViewport({ width: 1280, height: 720 });
await page.goto('https://example.com', {
waitUntil: 'networkidle2'
});
await page.screenshot({ path: 'screenshot.png', fullPage: true });
console.log('Chụp ảnh lưu tại: screenshot.png');
} catch (error) {
console.error('Lỗi:', error);
}
}
takeScreenshot();Ví dụ 3: Tạo file PDF
Tạo file generate-pdf.js:
const puppeteer = require('puppeteer');
async function generatePDF() {
const browser = await puppeteer.connect({
browserWSEndpoint: 'ws://localhost:3000',
});
try {
const page = await browser.newPage();
await page.goto('https://example.com', {
waitUntil: 'networkidle2'
});
await page.pdf({ path: 'document.pdf', format: 'A4' });
console.log('PDF được lưu tại: document.pdf');
} catch (error) {
console.error('Lỗi:', error);
}
}
generatePDF();Ví dụ 4: Web Scraping (Lấy dữ liệu)
Tạo file scrape.js:
const puppeteer = require('puppeteer');
async function scrapeData() {
const browser = await puppeteer.connect({
browserWSEndpoint: 'ws://localhost:3000',
});
try {
const page = await browser.newPage();
await page.goto('https://example.com', {
waitUntil: 'networkidle2'
});
// Lấy tất cả các heading
const headings = await page.$$eval('h1', elements =>
elements.map(el => el.textContent)
);
console.log('Các tiêu đề tìm thấy:', headings);
} catch (error) {
console.error('Lỗi:', error);
}
}
scrapeData();Ví dụ 5: Đăng nhập và tự động hóa
Tạo file automate-login.js:
const puppeteer = require('puppeteer');
async function autoLogin() {
const browser = await puppeteer.connect({
browserWSEndpoint: 'ws://localhost:3000',
});
try {
const page = await browser.newPage();
await page.goto('https://example.com/login', {
waitUntil: 'networkidle2'
});
// Điền email
await page.type('input[name="email"]', '[email protected]');
// Điền mật khẩu
await page.type('input[name="password"]', 'password123');
// Nhấp nút Login
await Promise.all([
page.click('button[type="submit"]'),
page.waitForNavigation({ waitUntil: 'networkidle2' })
]);
console.log('Đã đăng nhập thành công!');
// Lấy dữ liệu sau khi đăng nhập
const content = await page.content();
console.log('Trang sau đăng nhập được tải');
} catch (error) {
console.error('Lỗi:', error);
}
}
autoLogin();Xử lý lỗi phổ biến
Lỗi 1: Không thể kết nối tới Browserless
Lỗi:
Error: connect ECONNREFUSED 127.0.0.1:3000
Nguyên Nhân: Container Docker không chạy hoặc cổng không đúng
Giải pháp:
# Kiểm tra container đang chạy
docker ps
# Nếu chưa chạy, khởi động lại
docker run -p 3000:3000 ghcr.io/browserless/chromiumLỗi 2: Hết bộ nhớ (Out of Memory)
Lỗi:
Error: Cannot allocate memory
Giải pháp:
- Giảm
MAX_CONCURRENT_SESSIONS - Tăng RAM dành cho Docker
- Đóng các trình duyệt không cần thiết
docker run -p 3000:3000 \
-e MAX_CONCURRENT_SESSIONS=3 \
-m 4g \
ghcr.io/browserless/chromiumLỗi 3: Timeout
Lỗi:
Error: Navigation timeout of 30000 ms exceeded
Giải pháp: Tăng timeout:
await page.goto('https://example.com', {
waitUntil: 'networkidle2',
timeout: 60000 // 60 giây thay vì 30 giây
});Lỗi 4: Session tạm dừng
Lỗi:
Error: Session exceeded max time
Giải pháp: Tăng biến TIMEOUT:
docker run -p 3000:3000 \
-e TIMEOUT=60000 \
ghcr.io/browserless/chromiumMẹo tối ưu hóa
1. Sử dụng Connection Pooling
Tái sử dụng kết nối thay vì tạo mới mỗi lần:
let browser = null;
async function getBrowser() {
if (!browser) {
browser = await puppeteer.connect({
browserWSEndpoint: 'ws://localhost:3000',
});
}
return browser;
}
async function task1() {
const browser = await getBrowser();
const page = await browser.newPage();
// ... công việc
await page.close(); // Chỉ đóng page, không đóng browser
}
async function task2() {
const browser = await getBrowser();
const page = await browser.newPage();
// ... công việc
await page.close();
}2. Đặt viewport cố định
Giảm bộ nhớ bằng cách giới hạn kích thước viewport:
await page.setViewport({ width: 1024, height: 768 });3. Vô hiệu hóa hình ảnh
Tăng tốc độ bằng cách không tải hình ảnh:
await page.setRequestInterception(true);
page.on('request', (request) => {
if (['image', 'stylesheet', 'font'].includes(request.resourceType())) {
request.abort();
} else {
request.continue();
}
});4. Sử dụng Headless Mode thích hợp
Kiểm tra tài liệu Browserless để chọn image phù hợp:
# Chromium (nhẹ)
ghcr.io/browserless/chromium
# Chrome đầy đủ
ghcr.io/browserless/chrome
# Firefox
ghcr.io/browserless/firefox
# Tất cả các trình duyệt
ghcr.io/browserless/multi
5. Giám sát và logging
Bật debug mode để theo dõi hoạt động:
docker run -p 3000:3000 \
-e DEBUG=true \
ghcr.io/browserless/chromiumCâu hỏi thường gặp
Q: Browserless có miễn phí không?
A: Có, miễn phí cho mục đích không thương mại. Để sử dụng thương mại, bạn cần mua giấy phép.
Q: Tôi có thể sử dụng Playwright thay vì Puppeteer không?
A: Có, Browserless hỗ trợ cả Puppeteer và Playwright.
Q: Có thể chạy trên cloud không?
A: Có, Browserless có thể chạy trên bất kỳ nền tảng hỗ trợ Docker (AWS, Google Cloud, Azure, DigitalOcean, v.v.).
Q: Làm cách nào để giám sát hiệu suất?
A: Truy cập http://localhost:3000/docs để xem tài liệu API và trạng thái.
Browserless là công cụ tuyệt vời cho bất kỳ ai cần tự động hóa các tác vụ web. Nó cung cấp:
- Sự linh hoạt: Chạy bất kỳ script Puppeteer/Playwright nào
- Độ tin cậy: Quản lý tài nguyên tự động, không bị lỗi Chrome
- Dễ triển khai: Chỉ cần Docker, không cần cấu hình phức tạp
- Khả năng mở rộng: Hỗ trợ hàng loạt session đồng thời
- Mã nguồn mở: Miễn phí cho mục đích không thương mại
Bước tiếp theo
- Cài đặt Browserless trên máy tính của bạn
- Thử các ví dụ trong bài viết này
- Khám phá tài liệu chính thức tại https://docs.browserless.io/
- Tham gia cộng đồng trên GitHub để nhận hỗ trợ








