VeilRender
中文 | 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.
Features
- Stealth rendering — CloakBrowser (71 C++ fingerprint patches) + Patchright (stealth Playwright fork)
- Multiple output formats — raw HTML, Markdown, readability-extracted article text
- Screenshot capture — full-page or viewport PNG
- 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 —
/metricsendpoint 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 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
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:9222orhttp://host:9222— Chromium CDP workerplaywright://host:1234/ws-path— Firefox/Camoufox Playwright workerplaywrights://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
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
License
MIT
Release files for veilrender 0.4.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| veilrender-0.4.1.tar.gz | 638.8 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| veilrender-0.4.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 1.3 MB
Release files / veilrender-0.4.1.tar.gz
| Download URL | veilrender-0.4.1.tar.gz |
|---|---|
| Size | 638.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
a3c539ab3caa16fa9add2f233659c360a0861b96a54e9f834d91af2f13271ac6
|
|
BLAKE2b-256 checksum How to use checksums |
b5b77acc397c5fe117de2e233c66edbed16adce5be7112ed2a62807cfd1e984f
|
| 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 Aug 25, 2026.
Transparency logRelease files / veilrender-0.4.1-py3-none-any.whl
| Download URL | veilrender-0.4.1-py3-none-any.whl |
|---|---|
| Size | 644.1 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
7eab92412cfc8f855da0a4bc15e18aa2ac8b4724d19967a37cdb5767be183f01
|
|
BLAKE2b-256 checksum How to use checksums |
7e79fe8980a8274d5567756e9e9085d5a673bbc44b03cfccc03c9bcd1a63f950
|
| 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 Aug 25, 2026.
Transparency log