Skip to main content

Migrating from Cloud to Self-Hosted

This guide covers the differences between Browserless Cloud and a self-hosted Enterprise deployment, and walks through the steps to migrate.

What Changes

  • Connection URLs change from wss://production-sfo.browserless.io (or other regional endpoints) to your self-hosted address.
  • Authentication: Cloud uses a cloud API token tied to your account. Self-hosted uses the TOKEN env var you configure.
  • EXTERNAL env var: Set EXTERNAL to your public-facing URL. Without it, reconnect and LiveURL URLs contain localhost:3000, which is unreachable by clients. This is the most common migration pitfall.
  • No residential proxies by default: Cloud provides managed proxy vendors. Self-hosted does not include proxy credentials. Bring your own proxy server and configure it per-request via BQL proxy() mutation or launch args. Browserless also sells proxy access for self-hosted customers. Contact sales for details.
  • Metrics are local: Use the /metrics endpoint or configure OpenTelemetry. There is no cloud dashboard for self-hosted.
  • Infrastructure is yours: You manage scaling, updates, container orchestration, and infrastructure.

What Stays the Same

  • All API endpoints (REST, WebSocket, BQL) use identical paths and request formats.
  • CDP commands (Browserless.reconnect, Browserless.liveURL, Browserless.closeLiveURL) work the same.
  • BQL queries and mutations require no changes.
  • Session management patterns (reconnect lifecycle, session persistence) are identical.
  • Connection URL format is the same. Only the host portion changes.

Migration Checklist

  1. Pull the enterprise image and authenticate with the private registry (see Deployment Guide).
  2. Set KEY (license key) and TOKEN (API auth) env vars.
  3. Set up additional tokens with appropriate roles if multiple teams will access the instance (see Token Roles).
  4. Set EXTERNAL to your public-facing URL, including protocol and port if non-standard.
  5. Add --shm-size=2g or --ipc=host to your Docker run command for Chrome shared memory.
  6. Test all endpoints: health check (/pressure), WebSocket connection, REST APIs, BQL.
  7. Update all client connection URLs from cloud endpoints to your self-hosted address.
  8. If using proxies, configure your own proxy server in BQL or launch args.
  9. Align reverse proxy/load balancer timeouts with the TIMEOUT env var (see Timeouts).

Common Pitfalls

Missing EXTERNAL: Reconnect URLs and LiveURL links contain localhost:3000, which is unreachable from client machines.

Missing --shm-size=2g: Chrome crashes with "out of memory" errors under load. Docker defaults shared memory to 64MB, which is not enough for Chrome.

Reverse proxy idle timeout shorter than session timeout: Connections drop silently with no error code. Set your proxy's read timeout above the TIMEOUT env var value (see Timeouts).