Open Source Deployment
The open-source version of Browserless lets you deploy headless browsers using Docker with full support for Puppeteer, Playwright, and REST APIs.
Key capabilities:
- Out-of-the-box browser images for Chromium, Chrome, Firefox, WebKit, and Edge
- Native support for Puppeteer and Playwright
- Built-in REST APIs for screenshots, PDFs, scraping, and more
- Debugging tools, session management, and health checks
Quick Start
Run Browserless Container
Running the docker image is similar to other
docker runcommands, and all options are passed in via environment variables. In the example below, we're starting the image with a maximum concurrency of10(further requests will be queued), and setting the token to6R0W53R135510.# Run Chromium with configuration
docker run \
--rm \
-p 3000:3000 \
-e "CONCURRENT=10" \
-e "TOKEN=6R0W53R135510" \
ghcr.io/browserless/chromium
# Or run all supported browsers
docker run \
--rm \
-p 3000:3000 \
-e "CONCURRENT=10" \
-e "TOKEN=6R0W53R135510" \
ghcr.io/browserless/multiwarningBrowserless is designed to always require a token. This means that, if you don't pass a
TOKENenv variable, a randomly generated token will be set.Connect Your Application
Here are complete examples of integrating Browserless into your application:
- Puppeteer
- Playwright
const express = require("express");
const puppeteer = require("puppeteer-core");
const app = express();
app.get("/image", async (req, res) => {
let browser;
try {
// This was puppeteer.launch()
browser = await puppeteer.connect({
browserWSEndpoint: "ws://localhost:3000?token=6R0W53R135510",
});
const page = await browser.newPage();
await page.goto("http://www.example.com/");
const data = await page.screenshot();
return res.end(data, "binary");
} catch (error) {
console.error("Error capturing screenshot:", error);
return res.status(500).send("Error capturing screenshot");
} finally {
if (browser) {
await browser.close();
}
}
});
app.listen(8080);- Javascript
- Python
- Java
- C#
const express = require('express');
const playwright = require('playwright');
const app = express();
app.get('/image', async (req, res) => {
let browser;
try {
browser = await playwright.chromium.connectOverCDP('ws://localhost:3000?token=6R0W53R135510');
const context = await browser.newContext();
const page = await context.newPage();
await page.goto('http://www.example.com/');
await new Promise((resolve) => setTimeout(resolve, 5000));
const data = await page.screenshot({ type: 'png' });
return res.end(data, 'binary');
} catch (error) {
console.error('Error capturing screenshot:', error);
return res.status(500).send('Error capturing screenshot');
} finally {
if (browser) {
await browser.close();
}
}
});
app.listen(8080);from flask import Flask, send_file
from playwright.sync_api import sync_playwright
import io
app = Flask(__name__)
@app.route("/image", methods=["GET"])
def capture_image():
try:
with sync_playwright() as p:
browser = p.chromium.connect_over_cdp("ws://localhost:3000?token=6R0W53R135510")
try:
context = browser.new_context()
page = context.new_page()
page.goto("http://www.example.com/")
page.wait_for_timeout(5000)
screenshot = page.screenshot(type="png")
return send_file(io.BytesIO(screenshot), mimetype="image/png")
finally:
browser.close()
except Exception as e:
print(f"Error capturing screenshot: {e}")
return "Error capturing screenshot", 500
if __name__ == "__main__":
app.run(port=8080)import com.microsoft.playwright.*;
import static spark.Spark.*;
import java.io.OutputStream;
public class PlaywrightImageServer {
public static void main(String[] args) {
port(8080);
get("/image", (req, res) -> {
Browser browser = null;
try (Playwright playwright = Playwright.create()) {
browser = playwright.chromium().connectOverCDP("ws://localhost:3000?token=6R0W53R135510");
BrowserContext context = browser.newContext();
Page page = context.newPage();
page.navigate("http://www.example.com/");
page.waitForTimeout(5000);
byte[] screenshot = page.screenshot(new Page.ScreenshotOptions().setType(ScreenshotType.PNG));
res.type("image/png");
OutputStream outputStream = res.raw().getOutputStream();
outputStream.write(screenshot);
outputStream.flush();
return res.raw();
} catch (Exception e) {
res.status(500);
return "Error capturing screenshot: " + e.getMessage();
} finally {
if (browser != null) {
browser.close();
}
}
});
}
}using System;
using System.IO;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Hosting;
using Microsoft.Playwright;
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
app.MapGet("/image", async context =>
{
IPlaywright? playwright = null;
IBrowser? browser = null;
try
{
playwright = await Playwright.CreateAsync();
browser = await playwright.Chromium.ConnectOverCDPAsync("ws://localhost:3000?token=6R0W53R135510");
var page = await (await browser.NewContextAsync()).NewPageAsync();
await page.GotoAsync("http://www.example.com/");
await Task.Delay(5000);
var screenshot = await page.ScreenshotAsync(new PageScreenshotOptions { Type = ScreenshotType.Png });
context.Response.ContentType = "image/png";
await context.Response.Body.WriteAsync(screenshot);
}
catch (Exception e)
{
context.Response.StatusCode = 500;
await context.Response.WriteAsync("Error capturing screenshot: " + e.Message);
}
finally
{
if (browser != null)
{
await browser.CloseAsync();
}
playwright?.Dispose();
}
});
app.Run("http://localhost:8080");Verify Setup
Test your deployment with a simple REST API call:
curl "http://localhost:3000/content?token=6R0W53R135510&url=https://example.com"This should return the HTML content of the example.com page, confirming your Browserless instance is working correctly.
Once running, visit http://localhost:3000/docs for API documentation.