← Docs

Session-bridge architecture

How gemini-chrome runs a persistent browser session inside an Azure VM behind Caddy and Cloudflare.

Azure VM — Sweden Central

A single Standard D2s v3 instance hosts the entire runtime. The region was chosen for low-latency peering with Cloudflare’s Stockholm edge. The VM runs Windows Server 2022 with Hyper-V disabled and RDP locked to a bastion-only subnet.

Headed Chromium

Chromium launches with --headless=new but keeps a virtual display via the Windows Desktop Session. A persistent user-data directory survives reboots, so cookies, localStorage, and service-worker registrations are retained across restarts.

Persistent profile

The profile directory is backed by the VM’s temporary disk (D:\). On startup a scheduled task snapshots the profile to Azure Blob cool tier every 15 minutes. If the VM is reprovisioned, the latest snapshot is restored before Chromium starts.

Caddy + TLS

Caddy terminates TLS with a Let’s Encrypt certificate for the internal hostname. It reverse-proxies the Chrome DevTools Protocol WebSocket on /cdp and serves a static health-check page on /. Mutual TLS is enforced for all non-health endpoints.

Cloudflare

Cloudflare sits in front of the Caddy listener. The origin is exposed only via a Cloudflare Tunnel (cloudflared), so no inbound ports are open on the Azure NSG. WAF rules block non-Meridian User-Agent strings and rate-limit WebSocket upgrade attempts to 5/s per IP.

Session lifecycle

A session is created when Meridian’s API calls the bridge’s POST /sessions endpoint. The bridge spawns a new browser context (not a full profile) so multiple users share one Chromium process safely. Idle contexts are evicted after 10 minutes. The bridge reports metrics to Meridian every 30 seconds via a dedicated telemetry pipe.