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
Run the Docker image with environment variables for configuration. This example starts Browserless with a maximum concurrency of
10(further requests queue) and sets 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.