Skip to main content

VeilRender

PyPI version GitHub release CI Docker Pulls License: MIT

中文 | English

Headless browser rendering API with stealth capabilities — self-hostable via Docker or pip.

VeilRender accepts a URL and returns the fully rendered page content (HTML, Markdown, readability-extracted article) using a stealth Chromium browser. Designed as a fallback for fetch tools that fail on JavaScript-rendered or bot-protected pages.

Dashboard

Features

  • Stealth renderingCloakBrowser (71 C++ fingerprint patches) + Patchright (stealth Playwright fork)
  • Multiple output formats — raw HTML, Markdown, readability-extracted article text
  • Screenshot capture — full-page, viewport, or element; PNG or JPEG with quality/scale control
  • Horizontal scaling — gateway + remote browser worker pool with health checks and auto-reconnection
  • Mixed browser backends — Chromium (CDP) and Firefox/Camoufox (Playwright protocol) in the same pool
  • Prometheus metrics/metrics endpoint with latency percentiles, per-worker gauges
  • Dashboard — live stats at / with i18n (en/zh), SVG capacity gauge
  • Ad/tracker blocking — 82k domain blocklist from StevenBlack/hosts
  • Render cache — L1 in-memory + L2 S3-compatible (R2, Oracle, AWS)
  • CDP proxy — direct WebSocket access to the browser at /cdp
  • Zero external deps (except patchright) — HTTP server, S3 client, HTML parsing all vendored

Quick Start

Docker (recommended)

# Single instance with embedded CloakBrowser
docker run -p 7860:7860 -e VEILRENDER_API_TOKEN=your-secret oaklight/veilrender:latest

# Gateway only (no browser, 336MB)
docker run -p 7860:7860 oaklight/veilrender:gateway

pip

pip install veilrender
veilrender  # starts on :7860, auto-downloads CloakBrowser binary on first run

Docker Compose — Worker Pool

# docker-compose.yaml
services:
  veilrender:
    image: oaklight/veilrender:gateway
    ports: ["7860:7860"]
    environment:
      - VEILRENDER_WORKERS=cdp://browser-worker:9222
  browser-worker:
    image: cloakhq/cloakbrowser
    command: ["cloakserve"]

See deploy/ for more compose examples including mixed Chromium+Camoufox pools.

API

GET /health

{"status": "ok"}

POST /render

Render a URL and return the page content.

curl -X POST http://localhost:7860/render \
  -H "Authorization: Bearer your-secret" \
  -H "Content-Type: application/json" \
  -d '{"url": "https://example.com", "formats": ["html", "readability", "markdown"]}'

Request body:

Field Type Default Description
url string (required) URL to render
formats string[] ["html"] Output formats: html, readability, markdown
wait_until string "load" Playwright wait strategy: load, domcontentloaded, networkidle

POST /screenshot

Capture a screenshot (PNG or JPEG).

Request body:

Field Type Default Description
url string (required) URL to capture
format string "png" Image format: png, jpeg
quality int JPEG quality 0–100 (only for jpeg)
full_page bool false Capture the full scrollable page
scale float Device pixel ratio (e.g. 2 for retina)
selector string CSS selector to screenshot a specific element
clip object Region to capture: {"x": N, "y": N, "width": N, "height": N}
color_scheme string "light", "dark", or "no-preference"
wait_for string CSS selector to wait for before capture
transparent bool false Transparent background (PNG only)
wait_until string "networkidle" Playwright wait strategy
timeout int Timeout in ms
viewport_width int Viewport width in px
viewport_height int Viewport height in px
# Default PNG screenshot
curl -X POST http://localhost:7860/screenshot \
  -H "Authorization: Bearer your-secret" \
  -H "Content-Type: application/json" \
  -d '{"url": "https://example.com"}' -o screenshot.png

# JPEG with quality
curl -X POST http://localhost:7860/screenshot \
  -H "Authorization: Bearer your-secret" \
  -H "Content-Type: application/json" \
  -d '{"url": "https://example.com", "format": "jpeg", "quality": 80}' \
  -o screenshot.jpg

# Element screenshot
curl -X POST http://localhost:7860/screenshot \
  -H "Authorization: Bearer your-secret" \
  -H "Content-Type: application/json" \
  -d '{"url": "https://example.com", "selector": "#main-content"}' \
  -o element.png

GET /metrics

Prometheus exposition format with uptime, request counters, cache stats, latency summaries (p50/p95), and per-worker health gauges.

GET /stats

JSON API for live dashboard data (polled by the dashboard UI).

WS /cdp

Direct CDP WebSocket proxy to the browser. Supports ?worker=N for targeting specific workers in a pool.

Configuration

All settings via VEILRENDER_* environment variables:

Core

Variable Default Description
VEILRENDER_API_TOKEN (none) Bearer token. If unset, auth is disabled
VEILRENDER_PORT 7860 Server port
VEILRENDER_HOST 0.0.0.0 Bind address
VEILRENDER_TIMEOUT 30000 Page load timeout (ms)
VEILRENDER_VIEWPORT_WIDTH 1280 Browser viewport width
VEILRENDER_VIEWPORT_HEIGHT 720 Browser viewport height
VEILRENDER_MAX_CONCURRENT 5 Max concurrent pages (single-instance)

Worker Pool

Variable Default Description
VEILRENDER_WORKERS (none) Comma-separated worker endpoints (enables pool mode)
VEILRENDER_WORKER_MAX_CONCURRENT 5 Per-worker page concurrency
VEILRENDER_WORKER_HEALTH_INTERVAL 10 Health check interval (seconds)

Worker endpoint formats:

  • cdp://host:9222 or http://host:9222 — Chromium CDP worker
  • playwright://host:1234/ws-path — Firefox/Camoufox Playwright worker
  • playwrights://host:1234/ws-path — TLS Playwright worker

Browser Binary

Variable Default Description
CLOAKBROWSER_BINARY (auto) Path to custom browser binary
CLOAKBROWSER_MIRROR (none) GitHub mirror URL for China (e.g. https://ghfast.top)

Binary detection cascade: env var → ~/.cloakbrowser/*/chrome → auto-download from GitHub Releases.

Cache & Storage

Variable Default Description
VEILRENDER_CACHE_ENABLED false Enable render caching
VEILRENDER_CACHE_TTL 86400 Cache TTL in seconds
VEILRENDER_RESOURCE_FILTER true Block ads/trackers during rendering
VEILRENDER_S3_ENDPOINT (none) S3 endpoint for L2 cache
VEILRENDER_S3_ACCESS_KEY (none) S3 access key
VEILRENDER_S3_SECRET_KEY (none) S3 secret key

Deployment Modes

Single Instance (full image, 1.07GB)

Embedded CloakBrowser — simplest setup, no external dependencies.

docker run -p 7860:7860 -e VEILRENDER_API_TOKEN=secret oaklight/veilrender:latest

Gateway + Worker Pool (gateway image, 336MB)

Browser containers scale independently. Gateway routes via least-connections.

services:
  veilrender:
    image: oaklight/veilrender:gateway
    environment:
      - VEILRENDER_WORKERS=cdp://worker1:9222,cdp://worker2:9222

  worker1:
    image: cloakhq/cloakbrowser
    command: ["cloakserve"]

  worker2:
    image: cloakhq/cloakbrowser
    command: ["cloakserve"]

Mixed Pool (Chromium + Camoufox)

Dual-engine stealth: CloakBrowser for Chromium-fingerprinted sites, Camoufox for Firefox-fingerprinted sites.

services:
  veilrender:
    image: oaklight/veilrender:gateway
    environment:
      - VEILRENDER_WORKERS=cdp://chromium:9222,playwright://camoufox:1234/ws

  chromium:
    image: cloakhq/cloakbrowser
    command: ["cloakserve"]

  camoufox:
    build: deploy/Dockerfile.camoufox

Local Browser Gateway (use your own cookies)

Connect the gateway to your desktop browser to render authenticated pages using your existing login sessions. Start Chromium with CDP enabled:

chromium --remote-debugging-port=9333

Then run the gateway container:

docker run --rm --network host \
  -e VEILRENDER_PORT=7880 \
  -e VEILRENDER_WORKERS=http://127.0.0.1:9333 \
  oaklight/veilrender:gateway

Now POST /render to localhost:7880 renders pages as your logged-in browser would — including sites behind authentication, Cloudflare challenges, etc.

Tip: Create a desktop shortcut for CDP-enabled Chromium so you can launch it from your application menu when needed. See AGENTS.md for details.

Note: Only Chromium-based browsers support CDP. Firefox/Waterfox cannot be used this way (they lack the Juggler protocol that Playwright requires). For Firefox-based stealth rendering, use Camoufox workers.

Docker Images

Tag Size Content
latest / 0.4.0 1.07GB Full — Patchright + CloakBrowser
gateway 336MB Gateway only — no browser binary

Build locally:

make build          # full image
make build-gateway  # gateway image

Development

# Setup
pip install -e ".[dev]"

# Run locally
make dev            # starts on :7860

# Lint & type check
make lint           # ruff check --fix && ruff format
make typecheck      # ty check

# Dev deploy
make deploy-dev SSH_TARGET=oaklight.buttercup

Community

Feel free to discuss the project via GitHub Issues or the LINUX DO community.

License

MIT

Release files for veilrender 0.5.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for veilrender 0.5.1
File Size Uploaded
veilrender-0.5.1.tar.gz 650.4 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for veilrender 0.5.1
File Interpreter ABI Platform
veilrender-0.5.1-py3-none-any.whl Python 3 none any Details

Total release size: 1.3 MB

Release files / veilrender-0.5.1.tar.gz

Download URL veilrender-0.5.1.tar.gz
Size 650.4 kB
Tags Source
SHA-256 checksum
How to use checksums
e33c7df4a34e5bda260cde97abe014f9ead87c53a0d9d88d12e0eb45e8be2163
BLAKE2b-256 checksum
How to use checksums
7a10250ae436cfacbaf9091d518b5c9181da5adac429d2a91f922b961459cab8
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 9, 2026.

Transparency log

Release files / veilrender-0.5.1-py3-none-any.whl

Download URL veilrender-0.5.1-py3-none-any.whl
Size 653.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
112511c26d4bceef3d11c68e6557ab48674a28ce20c1722deb70be457f037b44
BLAKE2b-256 checksum
How to use checksums
3b87c0ad791909cc57532c1090a410acfb369141b3be8f22afc078e42cc07f88
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 9, 2026.

Transparency log

Release history Release notifications | RSS feed

0.6.1

2 release files

0.6.0

2 release files

This release

0.5.1 This release

2 release files

0.5.0

2 release files

0.4.1

2 release files

0.4.0

2 release files

0.3.1

2 release files

0.3.0

2 release files

0.2.0

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page