Running in Docker
Run the gateway, the bauta browser, its font environments and a virtual display in one container.
The image runs bauta serve: the gateway, the bauta browser, the persona font environments, and a virtual display
for the browsers' windows. Each persona is an endpoint on port 9222.
Pull the image
docker pull ghcr.io/bautabrowser/bautaRun it
docker run -d --name bauta --init --cap-add=SYS_ADMIN -p 127.0.0.1:9222:9222 -v bauta:/data \
-e BAUTA_PERSONAS="shop=win-intel" ghcr.io/bautabrowser/bautaThen connect to a persona as on any machine:
browser = playwright.chromium.connect_over_cdp("http://127.0.0.1:9222/persona/shop")| flag | why |
|---|---|
--init | Reaps the browsers' exited processes. |
--cap-add=SYS_ADMIN | The browser's SUID sandbox helper makes the namespaces the sandbox needs, which takes this capability. |
-p 127.0.0.1:9222:9222 | Publishes port 9222 on the host's loopback only. |
-v bauta:/data | Keeps the license, the personas with their profiles, and the IP database. |
-e BAUTA_PERSONAS=... | Makes the personas that are missing at start. |
Port 9222 has no password. Publish it on the host's loopback (127.0.0.1:9222:9222), as above, or behind your own
access control.
Add a license key
-e BAUTA_LICENSE_KEY=<key> is optional. Without it the container runs the free plan (1 session).
docker run -d --name bauta --init --cap-add=SYS_ADMIN -p 127.0.0.1:9222:9222 -v bauta:/data \
-e BAUTA_LICENSE_KEY=<key> -e BAUTA_PERSONAS="shop=win-intel" ghcr.io/bautabrowser/bautaIn CI or with many containers, set a key, or keep /data on a volume so the container keeps its install id: the
server limits new free activations per IP. To use a license file instead of a key, put it at /data/license.
With an account, your license key is on your dashboard; see License keys and Plans.
Make personas
BAUTA_PERSONAS makes the personas that are missing at start, each name=<built-in or file>. Make others with
docker exec:
docker exec bauta bauta persona new crawl --from win-intelA persona file's settings (proxy, timezone, locale, humanize, ephemeral, requests) are the same as outside Docker.
From the packages, gateway (or BAUTA_GATEWAY) uses the container's gateway, whose personas you make there:
from bautabrowser import launch
browser = launch(gateway="http://127.0.0.1:9222", name="shop")const { launch } = require("bautabrowser");
const browser = await launch({ gateway: "http://127.0.0.1:9222", name: "shop" });WebGL and the GPU
Without a GPU in the container, the browsers render WebGL in software (Chrome's SwiftShader), and pages read the
persona's GPU. To render on the host's GPU instead, pass it in with --device /dev/dri:
docker run -d --name bauta --init --cap-add=SYS_ADMIN --device /dev/dri -p 127.0.0.1:9222:9222 -v bauta:/data \
-e BAUTA_PERSONAS="shop=win-intel" ghcr.io/bautabrowser/bautaThe sandbox stays on
The browser never runs with --no-sandbox. Its SUID sandbox helper makes the namespaces the sandbox needs, which
takes --cap-add=SYS_ADMIN. An image without the helper falls back to Chrome's user-namespace sandbox, which needs
--security-opt seccomp=unconfined and a host that lets unprivileged processes make user namespaces. Ubuntu 23.10
and later do not, by default, even to a container without AppArmor.
Build it yourself
From a checkout of the bauta-browser repository, fill
docker/dist/<arch>/ with the binaries, then build from the repository's root. From the latest release, with every
download checked against the release's signed SHA256SUMS:
docker/get.sh # or docker/get.sh vX.Y.Z; fills both amd64 and arm64
docker build -f docker/Dockerfile -t bauta .Or from a browser archive you already have, with your bauta binary:
docker/stage.sh bauta-browser-linux-x64.tar.gz /path/to/bauta amd64
docker build -f docker/Dockerfile -t bauta .