This project is supposed to provide a web proxy that renders the destination website wit playwright and returns the rendered html.
Any specific arguments are supposed to be passed as headers prefixed with "playwright-" which are stripped before the request is send to the destination
- Full JavaScript rendering: Executes all JavaScript on the page before returning HTML
- HTTP/HTTPS proxy: Works as a standard HTTP proxy compatible with
curl,wget, and other tools - WebSocket log streaming: Real-time log streaming via WebSocket at
/logsendpoint - Configurable port: Use command-line arguments or environment variables
- Extended timeouts: Handles slow-loading sites with 60-second navigation timeout
- Realistic browser: Uses a Chrome user-agent to avoid being blocked by anti-bot systems
- Kubernetes-ready: Includes Helm chart for easy Kubernetes deployment with k3s support
- Docker (for containerized deployment)
- Rust 1.96+ (for local development)
- Kubernetes 1.19+ and Helm 3.0+ (for Kubernetes deployment)
cargo build --releasedocker build -t playwright-proxy .The proxy port can be configured using either:
- Command-line argument:
./playwright-proxy 3000 - Environment variable:
PROXY_PORT=3000 ./playwright-proxy - Default: 3128 (if no argument or environment variable is provided)
Local execution:
./playwright-proxy 3128Docker execution:
docker run -p 3128:3128 playwright-proxy 3128# Install with default values
helm install playwright-proxy ./helm/playwright-proxy
# Upgrade existing release
helm upgrade playwright-proxy ./helm/playwright-proxy
# Uninstall
helm uninstall playwright-proxy# Install with custom replica count and autoscaling
helm install playwright-proxy ./helm/playwright-proxy \
--set replicaCount=3 \
--set autoscaling.enabled=true \
--set autoscaling.minReplicas=2 \
--set autoscaling.maxReplicas=10# Install with Ingress enabled
helm install playwright-proxy ./helm/playwright-proxy \
--set ingress.enabled=true \
--set ingress.className=nginx \
--set ingress.hosts[0].host=proxy.example.com \
--set ingress.hosts[0].paths[0].path=/ \
--set ingress.hosts[0].paths[0].pathType=Prefix# Install with custom image tag
helm install playwright-proxy ./helm/playwright-proxy \
--set image.tag=v0.2.0For more Helm configuration options, see helm/playwright-proxy/README.md.
If you're running on k3s and need WebSocket support for log streaming:
Option 1: Gateway API (Recommended for modern k3s)
# Use the Gateway API HTTPRoute configuration
helm install playwright-proxy ./helm/playwright-proxy \
-f helm/playwright-proxy/examples/k3s-gateway-api.yamlOption 2: Standard Ingress
# Use the k3s-specific Ingress configuration
helm install playwright-proxy ./helm/playwright-proxy \
-f helm/playwright-proxy/examples/k3s-traefik.yamlFor detailed WebSocket configuration and troubleshooting:
- Gateway API guide: GATEWAY_API.md
- WebSocket guide: WEBSOCKET_K3S.md
- Quick start: QUICKSTART_K3S_WEBSOCKET.md
Use as an HTTP proxy with curl:
# Render a website with JavaScript executed
curl --proxy "http://localhost:3128" http://www.google.com
# HTTPS URLs
curl --proxy "http://localhost:3128" https://example.com
# Instagram (note: may have limitations due to anti-bot measures)
curl --proxy "http://localhost:3128" https://www.instagram.com/usernameYou can also use it with other tools that support HTTP proxies:
# wget with proxy
wget -e use_proxy=yes -e http_proxy=http://localhost:3128 http://www.google.com
# Python requests
python -c "import requests; print(requests.get('http://www.google.com', proxies={'http': 'http://localhost:3128'}).text)"
# Set environment variables for system-wide proxy usage
export http_proxy=http://localhost:3128
export https_proxy=http://localhost:3128
curl https://example.comThe proxy returns the fully rendered HTML as plain text. Redirect to a file to save it:
curl --proxy "http://localhost:3128" https://example.com > rendered.html# The old format still works for backwards compatibility
curl http://localhost:3128/https://example.comConnect to the WebSocket endpoint to receive real-time logs:
# Using websocat
websocat ws://localhost:3128/logs
# Or from JavaScript/browser
const ws = new WebSocket('ws://localhost:3128/logs');
ws.onmessage = (event) => console.log(event.data);For k3s deployment, see WEBSOCKET_K3S.md for detailed configuration.
- Receives an HTTP request with a target URL
- Launches a Chromium browser context via Playwright
- Navigates to the target URL and waits for page load
- Waits 3 seconds for any additional dynamic content to render
- Extracts the full HTML content
- Returns the rendered HTML to the client
- Closes the browser context to free resources
- Performance: Each request creates a new browser context, so the proxy is slower than traditional proxies
- Resource usage: Requires significant memory and CPU for browser automation
- Anti-bot detection: Some sites (like Instagram) actively block automated access despite realistic user-agents
- JavaScript complexity: May not handle extremely complex or obfuscated JavaScript perfectly
The project includes a GitHub Actions workflow that:
- Validates the Helm chart on every push and pull request
- Builds and pushes Docker images to GitHub Container Registry (GHCR)
- Packages the Helm chart and creates releases on version tags
- Supports multi-architecture builds (linux/amd64, linux/arm64)
- Push to main: Builds Docker image and validates Helm chart
- Pull requests: Validates Helm chart and Rust code
- Version tags (
v*): Creates GitHub releases with Helm chart packages