Docker Configuration Reference
Configure Browserless Docker containers with environment variables. This page covers all available options for both open-source and Enterprise deployments.
For a step-by-step deployment walkthrough, see the Enterprise Deployment Guide.
Enterprise License & Authentication
| Variable | Description | Default | Required | Example |
|---|---|---|---|---|
KEY | Enterprise license key (activates enterprise features) | - | Enterprise only | ent_abc123... |
TOKEN | API authentication token for client requests. If not set, all endpoints are unauthenticated. Set TOKEN for any deployment accessible beyond localhost. | (none) | Recommended | my-secure-token |
KEY: Validates your enterprise license and unlocks enterprise featuresTOKEN: Authenticates client API requests (optional for private networks, recommended for production)- Never confuse these: Using
TOKENinstead ofKEYwill fail to activate enterprise features
Example:
docker run -p 3000:3000 \
-e "KEY=ent_abc123..." \
-e "TOKEN=my-secure-token" \
registry.browserless.io/browserless/browserless/enterprise:latest
Essential Configuration
| Variable | Description | Default | Example |
|---|---|---|---|
CONCURRENT / MAX_CONCURRENT_SESSIONS | Maximum concurrent browser sessions. Once reached, requests queue until workers are ready. Keep small initially and grow as needed | 10 | 20 |
QUEUED / QUEUE_LENGTH | Maximum queued requests before issuing 429 responses. If CONCURRENT=5 and QUEUED=5, then 10 total connections allowed (5 running + 5 pending) | 10 | 30 |
TIMEOUT | Session timeout in milliseconds. Set to -1 for no timeout (ensure proper cleanup in your scripts!) | 30000 | 300000 |
MAX_RECONNECT_TIME | Maximum allowed reconnection timeout limit (in milliseconds) for browser sessions after disconnection. Controls how long browsers remain available for reconnection via BrowserQL GraphQL or CDP WebSocket reconnect handlers. If unset, defaults to Infinity for backward compatibility | Infinity | 300000 |
PORT | Internal port for Browserless. Map externally via Docker's -p flag (e.g., -p 8080:3000) | 3000 | 8080 |
HOST | IP or domain to bind to. Defaults to localhost if not specified | localhost | 192.168.1.1 |
Example:
# Configure for 20 concurrent sessions, 30 queued, 5-minute timeout
docker run -p 3000:3000 \
-e "CONCURRENT=20" \
-e "QUEUED=30" \
-e "TIMEOUT=300000" \
registry.browserless.io/browserless/browserless/enterprise:latest
# Limit reconnection timeout to 5 minutes (300000ms)
docker run -p 3000:3000 \
-e "MAX_RECONNECT_TIME=300000" \
registry.browserless.io/browserless/browserless/enterprise:latest
# Map to external port 8080 and bind to specific host
docker run -p 8080:3000 \
-e "HOST=192.168.1.1" \
registry.browserless.io/browserless/browserless/enterprise:latest
# Disable session timeout (use with caution!)
docker run -p 3000:3000 -e "TIMEOUT=-1" registry.browserless.io/browserless/browserless/enterprise:latest
You can opt-out of timers by setting TIMEOUT=-1 for no session timer. Be sure to close connections when not in use to prevent resource exhaustion!
The MAX_RECONNECT_TIME environment variable allows administrators to control how long browser sessions remain available for reconnection after disconnection. This helps manage resource usage in enterprise environments by preventing browsers from staying open indefinitely while waiting for reconnection.
- When set: Any reconnect request (via BrowserQL GraphQL or CDP WebSocket) with a timeout exceeding this limit will be rejected with a clear error message
- When unset: Defaults to
Infinity, allowing unlimited reconnection timeouts (backward compatible behavior) - Validation: The limit is enforced in both BrowserQL GraphQL reconnect mutations and CDP WebSocket reconnect handlers
This setting is separate from TIMEOUT, which controls the overall session duration. MAX_RECONNECT_TIME specifically limits the reconnection window after a client disconnects.
Start with a low CONCURRENT value (5-10) and gradually increase it based on your hardware capacity. Running too many concurrent browser sessions can starve system resources. Monitor CPU and memory usage as you scale up.
Storage & Persistence
| Variable | Description | Default | Example |
|---|---|---|---|
DOWNLOAD_DIR | Directory for file downloads. Defaults to browserless-download-dirs inside OS temp directory | OS temp dir | /downloads |
DATA_DIR | User data directory for cookies, cache, and local storage. Forces all sessions to use same cache unless overridden per-session | OS temp dir | /user_data |
METRICS_JSON_PATH | Persistent metrics storage path. Browserless will read on startup and write periodically. Accessible via /metrics endpoint | - | /metrics/metrics.json |
When setting custom directories like DOWNLOAD_DIR or DATA_DIR, ensure you mount corresponding volumes in your Docker configuration to persist data across container restarts.
Example:
# Set custom download directory with volume mount
docker run -p 3000:3000 \
-e "DOWNLOAD_DIR=/downloads" \
-v /host/downloads:/downloads \
registry.browserless.io/browserless/browserless/enterprise:latest
# Persist user data (cookies, cache) and metrics
docker run -p 3000:3000 \
-e "DATA_DIR=/user_data" \
-e "METRICS_JSON_PATH=/metrics/metrics.json" \
-v /host/user_data:/user_data \
-v /host/metrics:/metrics \
registry.browserless.io/browserless/browserless/enterprise:latest
Security Settings
| Variable | Description | Default | Production Recommended |
|---|---|---|---|
ENABLE_CORS / CORS | Enable CORS headers for cross-origin requests | false | false |
ALLOW_GET | Allow GET requests with URL-encoded JSON in body query parameter (vs POST only) | false | false |
ALLOW_FILE_PROTOCOL | Allow file:// URLs (disabled by default for security) | false | false |
CORS_ALLOW_ORIGIN | Allowed CORS origins (when CORS enabled) | * | Specific domains |
CORS_ALLOW_METHODS | Allowed HTTP methods (when CORS enabled) | All | POST |
CORS_MAX_AGE | CORS preflight cache max age in seconds (when CORS enabled) | 2592000 | 300 |
Example:
# Enable CORS with specific origin and methods
docker run -p 3000:3000 \
-e "CORS=true" \
-e "CORS_ALLOW_ORIGIN=https://myapp.com" \
-e "CORS_ALLOW_METHODS=POST,DELETE" \
-e "CORS_MAX_AGE=300" \
registry.browserless.io/browserless/browserless/enterprise:latest
# Enable GET requests (useful for simple testing, not recommended for production)
docker run -p 3000:3000 \
-e "ALLOW_GET=true" \
registry.browserless.io/browserless/browserless/enterprise:latest
# Allow file:// protocol (use with caution)
docker run -p 3000:3000 \
-e "ALLOW_FILE_PROTOCOL=true" \
registry.browserless.io/browserless/browserless/enterprise:latest
For production deployments:
- Keep
CORS=falseor restrict origins to specific domains - Keep
ALLOW_GET=false(GET requests are less secure than POST) - Keep
ALLOW_FILE_PROTOCOL=falseunless absolutely required - Configure
TOKENfor API authentication
Health & Monitoring
| Variable | Description | Default | Example |
|---|---|---|---|
HEALTH / PRE_REQUEST_HEALTH_CHECK | Enable health checks before sessions. Returns 503 if CPU/memory thresholds exceeded | false | true |
MAX_MEMORY_PERCENT | Max memory % threshold before rejecting requests (requires HEALTH=true) | 99 | 90 |
MAX_CPU_PERCENT | Max CPU % threshold before rejecting requests (requires HEALTH=true) | 99 | 90 |
Example:
# Enable health checks with 80% CPU and memory thresholds
docker run -p 3000:3000 \
-e "HEALTH=true" \
-e "MAX_CPU_PERCENT=80" \
-e "MAX_MEMORY_PERCENT=80" \
registry.browserless.io/browserless/browserless/enterprise:latest
Enable health checks (HEALTH=true) in production to prevent overloading your instances. This is especially important when running multiple Browserless containers behind a load balancer, as it helps distribute load more effectively.
You can also query current system load at any time via the /pressure endpoint, which returns CPU, memory, running sessions, and queue depth.
Logging & Debugging
| Variable | Description | Default | Example |
|---|---|---|---|
DEBUG | Debug log patterns using debug module. Use * for all logs (very verbose), -* to disable, or patterns like browserless:*,-verbose | browserless* | browserless:*,-verbose |
TZ | Container timezone for log timestamps | UTC | America/New_York |
Example:
# Disable all debug logging
docker run -p 3000:3000 -e "DEBUG=-*" registry.browserless.io/browserless/browserless/enterprise:latest
# Enable all logging (generates lots of output!)
docker run -p 3000:3000 -e "DEBUG=*" registry.browserless.io/browserless/browserless/enterprise:latest
# Set timezone for logs
docker run -p 3000:3000 -e "TZ=America/New_York" registry.browserless.io/browserless/browserless/enterprise:latest
Using DEBUG=* will generate extensive log output from Browserless and all npm packages. This can significantly impact performance and disk space. Use sparingly and only for troubleshooting.
Browserless uses two logging systems. The DEBUG environment variable controls namespace-based log filtering (logs prefixed with browserless.io:). The LOG_LEVEL environment variable controls severity-based filtering (logs prefixed with the component name like server:trace: or enterprise-hooks:info:).
LOG_LEVEL accepts: trace (default), debug, info, warn, error, fatal. Setting LOG_LEVEL="info" suppresses trace and debug messages while keeping info, warnings, and errors.
To reduce log noise in production, a common configuration is:
LOG_LEVEL=info DEBUG=browserless*,-**:verbose
Logging & Observability
| Variable | Description | Default | Example |
|---|---|---|---|
LOG_LEVEL | Application log level. Controls the verbosity of Winston logger output. Values: trace, debug, info, warn, error, fatal, silent. | trace | info |
LOG_FORMAT | Log output format. Set to json for structured JSON logs suitable for log aggregation pipelines. | plain | json |
HEARTBEAT_INTERVAL | WebSocket heartbeat interval in milliseconds. The server sends a heartbeat ping to connected clients at this interval. Reduce this value when running behind load balancers with aggressive idle connection timeouts. | 30000 | 10000 |
OTEL_ENABLED | Enable OpenTelemetry instrumentation. See OpenTelemetry guide for all OTel variables. | false | true |
DISABLE_BLOCKLIST | Disable the built-in URL blocklist that prevents navigation to localhost, private IPs, and cloud metadata endpoints. | false | true |
Example:
# Production logging: structured JSON, info level, OTel enabled
docker run -p 3000:3000 \
-e "LOG_LEVEL=info" \
-e "LOG_FORMAT=json" \
-e "OTEL_ENABLED=true" \
-e "OTEL_EXPORTER_OTLP_ENDPOINT=http://collector:4318" \
registry.browserless.io/browserless/browserless/enterprise:latest
External Address Configuration
When using a load balancer or reverse proxy (like NGINX) in front of Browserless, you need to configure the external address so Browserless can generate correct external URLs (e.g., in the /sessions API).
| Variable | Description | Example |
|---|---|---|
EXTERNAL | Fully-qualified external URL for link generation | https://browserless.company.com |
The PROXY_URL environment variable is still supported for backward compatibility but is deprecated. Use EXTERNAL for new deployments.
See the NGINX Load Balancing guide for complete proxy setup instructions.
Example:
# Configure external address for proper link generation in /sessions API
docker run -p 3000:3000 \
-e "EXTERNAL=https://browserless.company.com" \
registry.browserless.io/browserless/browserless/enterprise:latest
The /sessions API will return properly formatted URLs:
[
{
"description": "",
"devtoolsFrontendUrl": "/devtools/inspector.html?wss=browserless.company.com/devtools/page/C6962B3428FC8E42CDA6484AB5B57EAC",
"id": "C6962B3428FC8E42CDA6484AB5B57EAC",
"title": "Example Domain",
"type": "page",
"url": "https://www.example.com/",
"webSocketDebuggerUrl": "wss://browserless.company.com/devtools/page/C6962B3428FC8E42CDA6484AB5B57EAC",
"browserId": "b519351a-355e-47d5-82cc-7c240cfa40f3",
"browserWSEndpoint": "wss://browserless.company.com/devtools/browser/b519351a-355e-47d5-82cc-7c240cfa40f3",
"port": "42169",
"trackingId": null
}
]
Webhook Alerts
Configure webhook URLs to receive alerts for various events:
| Variable | Trigger Event | Payload Includes |
|---|---|---|
QUEUE_ALERT_URL | When requests start queuing | Queue depth, timestamp |
REJECT_ALERT_URL | When requests are rejected (429) | Rejection reason, metrics |
TIMEOUT_ALERT_URL | When sessions timeout | Session info, duration |
ERROR_ALERT_URL | When unhandled errors occur | Error message |
FAILED_HEALTH_URL | When health check fails | CPU, memory, pressure |
See the Webhooks guide for payload details and examples.