Guides
Self-Hosting
BrowseFleet is fully open-source and designed to run on your own infrastructure. A single Docker container includes everything: the API server, Chrome, and all dependencies.
Quick Start with Docker
docker run -d \
--name browsefleet \
-p 3000:3000 \
--shm-size=2g \
-e API_KEYS=bf_your_secret_key \
-e MAX_CONCURRENT_SESSIONS=10 \
-v browsefleet-data:/data \
ghcr.io/therj/browsefleetDocker Compose
services:
browsefleet:
image: ghcr.io/therj/browsefleet
ports:
- "3000:3000"
environment:
- PORT=3000
- HOST=0.0.0.0
- API_KEYS=bf_your_secret_key
- MAX_CONCURRENT_SESSIONS=30
- STEALTH_DEFAULT=full
- LOG_LEVEL=info
- CHROME_PATH=/usr/bin/chromium
- DATA_DIR=/data
- CDP_EXTERNAL_HOST=your-server.example.com
- CDP_EXTERNAL_PORT=3000
- CDP_EXTERNAL_SCHEME=ws
volumes:
- browsefleet-data:/data
shm_size: '2gb'
deploy:
resources:
limits:
memory: 8G
restart: unless-stopped
volumes:
browsefleet-data:Environment Variables
| Variable | Default | Description |
|---|---|---|
PORT | 3000 | HTTP server port |
HOST | 0.0.0.0 | Server bind address |
API_KEYS | (empty) | Comma-separated API keys. Empty disables auth. |
MAX_CONCURRENT_SESSIONS | 30 | Maximum number of browser sessions at once |
DEFAULT_SESSION_TIMEOUT | 1800000 | Default session timeout in ms (30 minutes) |
MAX_SESSION_TIMEOUT | 86400000 | Maximum allowed session timeout in ms (24 hours) |
CHROME_PATH | (auto-detect) | Path to Chrome/Chromium binary |
STEALTH_DEFAULT | full | Default stealth level: none, basic, or full |
PROXY_URL | (empty) | Global proxy URL (HTTP or SOCKS5) |
CAPTCHA_API_KEY | (empty) | 2captcha API key for CAPTCHA solving |
CAPTCHA_PROVIDER | 2captcha | CAPTCHA provider (2captcha or anticaptcha) |
CDP_EXTERNAL_HOST | localhost | Hostname for client-facing CDP WebSocket URLs |
CDP_EXTERNAL_PORT | 3000 | Port for client-facing CDP WebSocket URLs |
CDP_EXTERNAL_SCHEME | ws | WebSocket scheme: ws or wss |
STRIPE_SECRET_KEY | (empty) | Stripe secret key for metered billing |
STRIPE_WEBHOOK_SECRET | (empty) | Stripe webhook signing secret |
STRIPE_PRICE_ID | (empty) | Stripe Price ID for the subscription product |
STRIPE_METER_EVENT_NAME | browser_hours | Stripe metered billing event name |
ANTHROPIC_API_KEY | (empty) | Anthropic API key for the Agent endpoint |
OPENAI_API_KEY | (empty) | OpenAI API key for the Agent endpoint |
DATA_DIR | ./data | Directory for SQLite DB, profiles, temp files |
LOG_LEVEL | info | Log level: trace, debug, info, warn, error, fatal |
Resource Requirements
| Resource | Minimum | Recommended | Notes |
|---|---|---|---|
| RAM per session | 150 MB | 300 MB | Depends on page complexity |
| RAM total (10 sessions) | 2 GB | 4 GB | Plus base OS and Node.js overhead |
| RAM total (30 sessions) | 6 GB | 12 GB | For production workloads |
| CPU | 2 cores | 4+ cores | Chrome is CPU-intensive for rendering |
| Disk | 2 GB | 10 GB | Profiles, temp files, SQLite DB |
| shm_size | 512 MB | 2 GB | Chrome uses /dev/shm for rendering |
Scaling
BrowseFleet runs as a single process managing multiple Chrome tabs. For higher concurrency:
Vertical scaling
Increase MAX_CONCURRENT_SESSIONS and add more RAM/CPU. A 64GB machine can comfortably run 100+ sessions.
Horizontal scaling
Run multiple BrowseFleet instances behind a load balancer. Each instance is stateless for quick actions. Sessions are pinned to their instance.
CDP WebSocket routing
If running multiple instances, route CDP WebSocket connections to the instance that owns the session. Use sticky sessions or encode the instance ID in the session ID.
Health Check
The GET /health endpoint returns HTTP 200 when the server is ready. The Docker image includes a built-in HEALTHCHECK that polls this endpoint every 30 seconds.
curl http://localhost:3000/health
# { "status": "ok" }