How to Deploy Browserless Enterprise with Docker
Deploy Browserless Enterprise with Docker Compose, configure its license and API token, secure the service, and verify it is ready for browser sessions.
To deploy Browserless Enterprise with Docker, log in to Browserless’s private registry, pull the Enterprise image, then run it with two separate credentials: KEY activates the Enterprise license, and TOKEN authenticates client requests. For production, pin an image version, use Docker Compose, increase Chrome’s shared memory, protect secrets, and size session concurrency against your own workload.
This guide uses Browserless’s official Enterprise image and deployment guidance. Registry credentials let you pull the image; they are distinct from the runtime Enterprise license key. Browserless’s deployment guide documents the image and verification endpoints; see the Enterprise Docker deployment guide and Docker configuration reference.
1. Prerequisites and credentials
- Docker installed on the host (and Docker Compose for the production example).
- A Browserless Enterprise license.
- Registry login credentials from Browserless, which authorize pulling the private image.
- A private API token you choose for authenticating client calls.
| Value | Purpose | Where it is used |
|---|---|---|
KEY |
Validates the Enterprise license and activates Enterprise features. | Container runtime configuration. |
TOKEN |
Authenticates requests to the running Browserless service. | Container configuration and client requests. |
| Registry credentials | Allows Docker to pull the private Enterprise image. | docker login; not a runtime API credential. |
Do not substitute one credential for another: setting TOKEN does not activate the Enterprise license. The configuration reference says that if TOKEN is unset, endpoints are unauthenticated, so configure it for any deployment reachable beyond localhost.
2. Log in and pull the Enterprise image
Use the registry credentials Browserless supplied:
docker login registry.browserless.io
Pull the Enterprise image:
docker pull registry.browserless.io/browserless/browserless/enterprise:latest
The official quickstart uses the latest tag. For production, pin a specific version so deployments are reproducible and upgrades are deliberate. Browserless gives 2.3.0 as an example tag; check the current Enterprise guide and your license materials for the version you intend to run. The guide lists support for ARM64 and AMD64, but confirm the tag and architecture available to your account before rollout.
3. Start a minimal Enterprise container
Replace the placeholders with your actual license key and a strong API token. Do not commit real credentials in shell history, source control, or shared deployment examples.
docker run -d \
--name browserless \
--restart unless-stopped \
-p 3000:3000 \
--shm-size=2g \
-e KEY=YOUR_ENTERPRISE_LICENSE_KEY \
-e TOKEN=YOUR_PRIVATE_API_TOKEN \
registry.browserless.io/browserless/browserless/enterprise:latest
Port 3000 is the container’s service port. The mapping above publishes it on host port 3000. The shared-memory option matters because Chrome uses /dev/shm; Browserless documents Docker’s default as 64 MB and recommends increasing it for production to avoid instability under load. --ipc=host is mentioned as an alternative in some environments, but it shares the host IPC namespace and may be less desirable for isolation.
4. Verify the deployment
After startup, use the documented endpoints to check the service. These commands verify HTTP responses from the deployment; they are not substitutes for observing it under your own traffic.
# API documentation
curl -i http://localhost:3000/docs
# Health/load information
curl -i http://localhost:3000/pressure
# Metrics
curl -i http://localhost:3000/metrics
Check container logs if an endpoint does not respond:
docker logs --tail=200 browserless
5. Production deployment with Docker Compose
Compose makes configuration easier to review and repeat. The following is an example, not a sizing guarantee: the concurrency, queue, timeout, and resource values come from Browserless’s sample production configuration. They are not universal recommendations or benchmark results. Measure your own workload and adjust them to the CPU, memory, page complexity, and job duration available on your host.
Create a compose.yaml file:
services:
browserless:
image: registry.browserless.io/browserless/browserless/enterprise:2.3.0
container_name: browserless
restart: unless-stopped
ports:
- "3000:3000"
environment:
KEY: ${BROWSERLESS_LICENSE_KEY}
TOKEN: ${BROWSERLESS_API_TOKEN}
CONCURRENT: "20"
QUEUED: "30"
TIMEOUT: "300000"
DATA_DIR: /user_data
METRICS_JSON_PATH: /metrics/metrics.json
shm_size: "2g"
volumes:
- browserless_user_data:/user_data
- browserless_metrics:/metrics
deploy:
resources:
limits:
cpus: "4"
memory: 8G
reservations:
cpus: "2"
memory: 4G
volumes:
browserless_user_data:
browserless_metrics:
Put the referenced values in a local .env file that is excluded from version control, or use your platform’s secret mechanism:
BROWSERLESS_LICENSE_KEY=YOUR_ENTERPRISE_LICENSE_KEY
BROWSERLESS_API_TOKEN=YOUR_PRIVATE_API_TOKEN
Start the service and inspect it:
docker compose up -d
docker compose ps
docker compose logs --tail=200 browserless
curl -i http://localhost:3000/pressure
Docker Compose resource reservations and limits are examples; actual enforcement depends on the Compose deployment environment. Confirm the host or orchestrator honors the settings you rely on. A pinned image tag also needs periodic, intentional updates: review Browserless’s current documentation and release information before upgrading.
6. Configure capacity, queueing, timeouts, and storage
Concurrency and queue
CONCURRENT caps simultaneous browser sessions. QUEUED controls how much pending work can wait for a session slot. When running and queued capacity is exhausted, excess requests can receive HTTP 429 responses. Lowering either value can protect a constrained host, while raising them can increase resource pressure. Start from the example only as a configuration baseline, then observe CPU, memory, queue pressure, and failure rates for your actual pages.
Timeouts and session cleanup
The documented default session timeout is 30,000 ms (30 seconds). Set TIMEOUT in milliseconds for longer jobs; the example uses 300,000 ms (five minutes). The configuration reference also documents TIMEOUT=-1 to disable the timer. Use that only when client code reliably closes browser sessions: otherwise abandoned sessions can consume resources indefinitely.
Persistent data and metrics
DATA_DIR sets a path for Browserless user data, and METRICS_JSON_PATH sets a metrics file location. Mount persistent volumes to those paths if the data should survive container replacement. Decide whether browser data should persist based on your application’s privacy and session-isolation requirements; persistence can retain cookies and cache beyond a single container lifetime.
7. Secure the service
- Set
TOKEN. An unset token leaves endpoints unauthenticated. Keep the token secret and rotate it using your organization’s normal credential process. - Prefer secret files or secret managers. Browserless’s production guidance shows
KEY_FILEandTOKEN_FILEwith Docker secrets. Avoid keeping credentials in source code or broadly readable environment files. Confirm the supported secret-file configuration for your image version. - Limit network exposure. Restrict inbound access at the host firewall, private network, or reverse proxy to the clients that need the service. Authentication does not replace network controls.
- Keep CORS disabled unless needed. If browser-based cross-origin clients require it, allow only the required origins rather than using a wildcard.
- Leave
ALLOW_GETfalse. Enable it only when there is a specific need for GET requests with encoded bodies. - Leave
ALLOW_FILE_PROTOCOLfalse. Allowfile://only if the workload needs it and the security implications are understood. - Use role-based tokens when teams need different access. The self-hosted token guide describes admin, developer, viewer, and public roles. It says the root token receives admin on first startup and tokens persist to disk across restarts; protect that root credential and consult the guide before delegating access.
See Browserless’s configuration reference and self-hosted token roles guide for current details.
8. Connect a client and make a request
For self-hosted deployments, clients connect to the host and port where the container is reachable and authenticate with the configured TOKEN. Browserless exposes APIs and WebSocket connections; the exact path and client library depend on whether the application uses REST, Puppeteer, Playwright, or another supported interface. The following curl request checks the documented content endpoint with a URL and token:
curl --fail-with-body --get \
"http://localhost:3000/chromium/content" \
--data-urlencode "token=${BROWSERLESS_API_TOKEN}" \
--data-urlencode "url=https://example.com"
For production, keep tokens out of URLs where infrastructure logs or browser histories might record them; use the authentication method supported by your chosen endpoint/client and protect logs. The endpoint above illustrates basic connectivity and should be checked against the current API documentation for your Browserless version.
9. Migrate from Browserless Cloud
A Cloud-to-self-hosted move requires changing the service URL and authentication configuration. Replace the Cloud endpoint with your self-hosted address and use the self-hosted TOKEN value. If Browserless returns reconnect or LiveURL links, set EXTERNAL to the public-facing service URL; otherwise generated links may contain localhost:3000, which remote clients cannot reach.
Managed residential proxies are not included by default in self-hosted Enterprise. If your workflows need proxies, provide your own and configure them per request. Browserless’s Cloud-to-self-hosted migration guide describes these differences.
10. Troubleshooting
| Symptom | Likely cause | What to do |
|---|---|---|
| Enterprise features do not activate | TOKEN was set, but KEY is missing or incorrect. |
Set the Enterprise license in KEY. Keep TOKEN for client authentication; it does not license the image. |
| Docker cannot pull the image | Registry login is missing, credentials are wrong, or the tag is unavailable to the account. | Run docker login registry.browserless.io with the credentials supplied by Browserless and check the image name and permitted tag. |
| Container exits at startup | License key, image access, version, or configuration may be invalid. | Inspect docker logs browserless; check the license and tag against current Browserless instructions. |
| Chrome crashes or behaves unstably under load | Container shared memory is too small. | Set shm_size: "2g" in Compose or --shm-size=2g with docker run, then observe memory pressure on the host. |
| Requests return 429 | The configured running-session and pending-queue capacity is exhausted. | Check /pressure, reduce incoming concurrency, or adjust CONCURRENT and QUEUED after evaluating available resources. |
| Sessions stop before jobs finish | The timeout is shorter than the job duration. | Increase TIMEOUT in milliseconds. If using -1, ensure every client closes sessions reliably. |
| Reconnect or LiveURL points to localhost | EXTERNAL was not set to the public address. |
Set EXTERNAL to the URL clients can reach, including the correct scheme and hostname. |
| Clients cannot connect from another container | Containers may not share a Docker network, or firewall/host settings block access. | Put both services on a shared network, use the Browserless service name and container port, and check firewall rules and any HOST override. |
| Requests fail through a reverse proxy | The proxy may not forward WebSocket traffic or the generated public URL is wrong. | Check proxy support for the connection type and configure EXTERNAL as described in the migration/deployment docs. |
| CORS errors in a browser client | Cross-origin access is disabled or the allowed origin does not match. | Prefer server-side clients. If browser access is required, enable CORS narrowly for the exact origin and methods needed. |
11. Performance, reliability, and operating cost
Browser workloads vary substantially with page size, JavaScript execution, media, navigation behavior, and how long clients keep sessions open. The cited Browserless documentation gives example resource limits and concurrency values but no universal sizing formula or benchmark. Treat capacity as an operational question: observe /pressure and /metrics, watch host CPU and memory, track 429s and timeout frequency, then adjust concurrency and queue limits based on the workload.
Reliability depends on more than the container staying up. Use a restart policy, health monitoring, a deliberate image-upgrade process, persistent volumes only where needed, and backups for any required persistent state. For multiple instances, use a load-balancing design appropriate to Browserless sessions and connection behavior; consult Browserless’s deployment documentation rather than assuming ordinary stateless HTTP balancing is sufficient.
With Enterprise Docker, your organization operates the host infrastructure and pays its associated compute, storage, network, monitoring, and maintenance costs, alongside the Browserless license. The research sources do not provide a universal infrastructure cost or prescribe a cloud provider, so estimate using your expected traffic and measured resource consumption.
12. When to self-host and when to use a managed option
Self-hosting suits teams that need control over data location, network policies, or isolated infrastructure, and that can operate the containers, capacity, monitoring, and security themselves. A managed Browserless deployment can reduce that infrastructure responsibility, while self-hosting puts scaling and operational controls in your hands. Proxy arrangements also differ: the self-hosted image does not include managed residential proxies by default. Browserless’s current product docs distinguish Enterprise from its open-source self-hosted image by documenting Enterprise capabilities such as BrowserQL, stealth and CAPTCHA solving, session recording, live debugging, webhooks, and OpenTelemetry; verify current plan details before choosing.
13. Or skip the browser setup
If the job is to capture website screenshots rather than operate a browser automation service, ScreenshotNeo is a website screenshot API and MCP server. One GET request returns an image or PDF, while the API handles the browser capture infrastructure. It is a different service from Browserless Enterprise and does not provide a Browserless deployment.
See the ScreenshotNeo API documentation. This cURL example saves a WebP screenshot:
curl -G "https://api.screenshotneo.com/v1/shot" \
-d access_key=YOUR_API_KEY \
--data-urlencode url=https://stripe.com \
-o shot.webp
- Cookie and consent banners, newsletter popups, and chat widgets are removed before the shot; each step can be turned off.
- Bot checks, blank pages, failed loads, timeouts, and cache hits are not billed. Response headers identify the page verdict and billing status.
- An MCP server provides screenshot tools for Claude, Cursor, and other MCP clients.
- The free plan includes 1,000 screenshots per month with no card; paid plans start at $5 for 3,000 screenshots.
Sign up free for 1,000 screenshots a month, with no card required.
FAQ
Can I use the Enterprise license key as my API token?
No. KEY activates Enterprise licensing; TOKEN authenticates service requests.
Does self-hosted Enterprise include residential proxies?
Not by default. Provide and configure your own proxy service if your workload needs one.
Is the Compose example a recommended minimum server size?
No. Its values are an example from the deployment guidance, not a benchmark or sizing promise. Choose capacity from observed workload behavior and available resources.
What should I change first when moving from Cloud?
Update the endpoint and token configuration, then set EXTERNAL if returned links must be reachable outside the host.


