Skip to main content
Deploy a web application inside an E2B sandbox, get a public URL, then use a Kernel cloud browser to visit every route, capture screenshots, and produce a structured preview report — all without running a browser locally.

Architecture

This example combines two services:
  1. E2B Sandbox — a secure cloud environment where the web app runs. E2B exposes the app at a public HTTPS URL via sandbox.get_host(port).
  2. Kernel Cloud Browser — a remote Chromium instance controlled through Playwright’s CDP protocol. It navigates the public URL, takes screenshots, and collects page metadata.
The orchestrator script on your machine creates the sandbox, deploys the app, and then runs a browsing script inside the sandbox that connects to a Kernel browser and screenshots each route.

Prerequisites

pip install e2b
Set both keys in your environment:
.env
E2B_API_KEY=e2b_***
KERNEL_API_KEY=kernel_***

How it works

1

Create the sandbox

Start an E2B sandbox using the kernel-browser template, which comes with the Kernel SDK and Playwright client pre-installed. No local browser binary is needed — Kernel provides the browser remotely.
from e2b import Sandbox

sandbox = Sandbox.create(
    "kernel-browser",
    envs={"KERNEL_API_KEY": os.environ["KERNEL_API_KEY"]},
    timeout=300,
)
2

Deploy the web app

Write a FastAPI application into the sandbox and start it as a background process on port 8000.
sandbox.files.write("/home/user/app.py", FASTAPI_APP)
sandbox.commands.run(
    "pip install --break-system-packages fastapi uvicorn",
    timeout=60,
)
sandbox.commands.run(
    "uvicorn app:app --host 0.0.0.0 --port 8000",
    background=True,
    cwd="/home/user",
)
3

Get the public URL

E2B exposes any sandbox port as a public HTTPS endpoint.
host = sandbox.get_host(8000)
app_url = f"https://{host}"
4

Browse with Kernel

A script running inside the sandbox creates a Kernel cloud browser, connects via Playwright CDP, and visits each route to take screenshots.
from kernel import Kernel
from playwright.sync_api import sync_playwright

kernel = Kernel()
kb = kernel.browsers.create()

with sync_playwright() as pw:
    browser = pw.chromium.connect_over_cdp(kb.cdp_ws_url)
    page = browser.new_page()
    page.set_viewport_size({"width": 1280, "height": 720})

    page.goto(app_url, wait_until="networkidle")
    page.screenshot(path="/home/user/screenshots/home.png")
5

Generate the preview report

After visiting every route, the script writes a JSON report with page titles and screenshot paths. The orchestrator reads it back from the sandbox.
import json

report = json.loads(
    sandbox.files.read("/home/user/preview_report.json")
)
for entry in report:
    print(f"Route: {entry['route']} — Title: {entry['title']}")

Full example

app_preview.py
"""
App Preview — E2B + Kernel

Spins up a web app inside an E2B sandbox, exposes it at a public URL,
then uses a Kernel cloud browser to navigate the app, take screenshots
of each route, and generate a visual preview report.
"""

import os
import time
import json

from e2b import Sandbox

# A sample FastAPI app to deploy inside the sandbox
FASTAPI_APP = '''
from fastapi import FastAPI
from fastapi.responses import HTMLResponse

app = FastAPI()

@app.get("/", response_class=HTMLResponse)
def home():
    return """
    <!DOCTYPE html>
    <html>
    <head><title>My App</title></head>
    <body><h1>Welcome to My App</h1></body>
    </html>
    """

@app.get("/about", response_class=HTMLResponse)
def about():
    return """
    <!DOCTYPE html>
    <html>
    <head><title>About</title></head>
    <body><h1>About</h1><p>E2B + Kernel integration demo.</p></body>
    </html>
    """

@app.get("/api/status")
def status():
    return {"status": "ok", "sandbox": "e2b", "browser": "kernel"}
'''

# Script that runs inside the sandbox to browse the app with Kernel
BROWSE_SCRIPT = '''
import sys
import json
from kernel import Kernel
from playwright.sync_api import sync_playwright

app_url = sys.argv[1]
routes = ["/", "/about"]

kernel = Kernel()
kb = kernel.browsers.create()

results = []

with sync_playwright() as pw:
    browser = pw.chromium.connect_over_cdp(kb.cdp_ws_url)
    page = browser.new_page()
    page.set_viewport_size({"width": 1280, "height": 720})

    for route in routes:
        url = f"{app_url}{route}"
        page.goto(url, wait_until="networkidle", timeout=15000)

        # Take screenshot
        safe_name = route.strip("/").replace("/", "_") or "home"
        screenshot_path = f"/home/user/screenshots/{safe_name}.png"
        page.screenshot(path=screenshot_path)

        # Collect page info
        results.append({
            "route": route,
            "title": page.title(),
            "screenshot": screenshot_path,
        })

    browser.close()

with open("/home/user/preview_report.json", "w") as f:
    json.dump(results, f)
'''


def main():
    sandbox = Sandbox.create(
        "kernel-browser",
        envs={"KERNEL_API_KEY": os.environ["KERNEL_API_KEY"]},
        timeout=300,
    )

    try:
        # Deploy and start the FastAPI app
        sandbox.files.write("/home/user/app.py", FASTAPI_APP)
        sandbox.commands.run("mkdir -p /home/user/screenshots", timeout=5)
        sandbox.commands.run(
            "pip install --break-system-packages fastapi uvicorn",
            timeout=60,
        )
        sandbox.commands.run(
            "uvicorn app:app --host 0.0.0.0 --port 8000",
            background=True,
            cwd="/home/user",
        )
        time.sleep(3)

        # Get the public URL
        host = sandbox.get_host(8000)
        app_url = f"https://{host}"
        print(f"App is live at: {app_url}")

        # Use Kernel browser to preview the app
        sandbox.files.write("/home/user/browse.py", BROWSE_SCRIPT)
        result = sandbox.commands.run(
            f'python3 /home/user/browse.py "{app_url}"',
            timeout=120,
        )

        # Read the preview report
        report = json.loads(
            sandbox.files.read("/home/user/preview_report.json")
        )
        for entry in report:
            print(f"Route: {entry['route']} — Title: {entry['title']}")

    finally:
        sandbox.kill()


if __name__ == "__main__":
    main()

Key concepts

ConceptDetail
E2B templatekernel-browser — pre-built with the Kernel SDK and Playwright client
Public URLsandbox.get_host(port) returns an HTTPS hostname
Background processsandbox.commands.run(..., background=True) starts the web server without blocking
Kernel browserkernel.browsers.create() spins up a remote Chromium; connect via kb.cdp_ws_url
CDP connectionPlaywright’s connect_over_cdp() drives the remote browser with full API access

Adapting this example

  • Your own app — replace FASTAPI_APP with any web framework (Next.js, Flask, Express). Adjust the install commands and start script accordingly.
  • More routes — add paths to the routes list in BROWSE_SCRIPT to screenshot additional pages.
  • Visual regression — compare screenshots across deploys to catch UI regressions automatically.
  • CI integration — run this as a post-deploy step to generate preview links and thumbnails for pull requests.