Skip to content

Deployment

Start with the quick start. For a deployment used by other machines, configure the database password, API keys, and network access before you expose the server.

You operate and update this service for your applications. To move browser CPU and memory use off application servers, deploy workers on separate hosts. The scaling guide shows the required network connections.

Apps -> TLS proxy -> Server -> private browser workers
|
v
PostgreSQL
Workers -> Server: registration and heartbeats

Before the first start, put a strong POSTGRES_PASSWORD in a .env file next to docker-compose.yaml. The Compose file passes it to PostgreSQL and the server’s database connection string.

PostgreSQL reads this password when it initializes an empty volume. Changing .env later does not change the password in an existing database. Use normal PostgreSQL password rotation procedures for an existing installation.

Keep the postgres-data volume and back it up. It contains sessions, workers, and API keys. Use docker compose down to stop the deployment while retaining the volume. The -v option deletes volumes and their data.

With the server still bound to localhost, create the first key:

Terminal window
docker compose exec server server apikey create --name grid

Save the returned key. Creating it immediately enables authentication across the service. Set the worker key in .env:

WORKER_API_KEY=pwd_replace_with_your_key

Recreate the workers so they receive the key:

Terminal window
docker compose up -d --force-recreate worker

Give clients a key before they connect. Workers also need keys for registration and heartbeats. Do not commit .env or keys to Git.

The server needs access to PostgreSQL and to every worker’s advertised WebSocket address. Workers need HTTP access to the server.

Expose only the server to clients. Keep PostgreSQL and worker ports on private networks. Put the client endpoint behind a TLS reverse proxy or a suitable private network. API keys do not encrypt http:// or ws:// traffic.

A reverse proxy must support WebSocket upgrades and timeouts that allow your sessions to run. If the proxy runs on the same host, it can reach the default 127.0.0.1:8080 mapping. A proxy in a separate container needs a shared Docker network or another route to the server.

  • GET /healthz checks process health.
  • GET /readyz checks database readiness.
  • GET /v1/capacity reports browser slots and queue depth; it needs a key after authentication is enabled.

Keep the Compose stop grace period longer than the application’s shutdown window. The supplied file uses 60 seconds and sets worker DRAIN_TIMEOUT=30. The worker’s standalone default drain timeout is 300 seconds.

For workers on separate hosts, follow scaling.