ScreenshotNeo

BlogHow-to

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.

By the ScreenshotNeo team4 October 202610 min read

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_FILE and TOKEN_FILE with 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_GET false. Enable it only when there is a specific need for GET requests with encoded bodies.
  • Leave ALLOW_FILE_PROTOCOL false. Allow file:// 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.

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.

Official references