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
TOKENenv var you configure. - EXTERNAL env var: Set
EXTERNALto your public-facing URL. Without it, reconnect and LiveURL URLs containlocalhost: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
/metricsendpoint 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
- Pull the enterprise image and authenticate with the private registry (see Deployment Guide).
- Set
KEY(license key) andTOKEN(API auth) env vars. - Set up additional tokens with appropriate roles if multiple teams will access the instance (see Token Roles).
- Set
EXTERNALto your public-facing URL, including protocol and port if non-standard. - Add
--shm-size=2gor--ipc=hostto your Docker run command for Chrome shared memory. - Test all endpoints: health check (
/pressure), WebSocket connection, REST APIs, BQL. - Update all client connection URLs from cloud endpoints to your self-hosted address.
- If using proxies, configure your own proxy server in BQL or launch args.
- Align reverse proxy/load balancer timeouts with the
TIMEOUTenv 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).