Deployment
Capium runs anywhere Python and Chromium run. The one rule for servers: run the browser headed under a virtual display, and provide the license at runtime, never in the image.
Docker
Install the SDK, Playwright's OS libraries, and Xvfb. Pass the license via an environment variable at docker run time so it never lands in a layer.
FROM python:3.12-slim
# Xvfb lets us run the browser HEADED on a server (recommended mode).
RUN apt-get update && apt-get install -y --no-install-recommends xvfb \
&& rm -rf /var/lib/apt/lists/*
RUN pip install --no-cache-dir capium playwright \
&& python -m playwright install-deps chromium
WORKDIR /app
COPY . .
# Provide the license at runtime, never bake it into the image.
ENV DISPLAY=:99
CMD Xvfb :99 -screen 0 1920x1080x24 & python your_script.pydocker run --rm \
-e CAPIUM_LICENSE_KEY=your-key \
your-imageHeadless Linux
True headless mode is the least stealthy option. On a server with no display, start Xvfb and export DISPLAY so the browser launches headed. See Installation for the base commands.
CI / CD
The same pattern works in CI. Store the key as a secret and inject it as CAPIUM_LICENSE_KEY. Remember each concurrent job consumes one session slot on your plan.
# .github/workflows/scrape.yml
jobs:
run:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with: { python-version: "3.12" }
- run: pip install capium playwright && python -m playwright install-deps chromium
- run: |
Xvfb :99 -screen 0 1920x1080x24 &
export DISPLAY=:99
python your_script.py
env:
CAPIUM_LICENSE_KEY: ${{ secrets.CAPIUM_LICENSE_KEY }}Cloud VMs & the GPU caveat
- Any Linux VM works; give it enough RAM for a Chromium process (roughly 1 GB per browser is a safe floor).
- For the hardest anti-bot targets, prefer a host with a real or virtualized GPU. Software-only rendering on a GPU-less box can surface WebGL/canvas tells, see Verifying stealth.
- Run a persona on a matching-OS host where you can; cross-OS rendering can be a tell.
Scaling
For a stable fleet of accounts, pin one seed + one persistent profile + one sticky proxy per identity, and keep concurrency within your plan's cap. See Async & persistent sessions.