Deploying Browserless
Introduction
Browserless is a powerful open-source headless browser automation platform that provides a robust, scalable solution for running Chrome and Chromium browsers in the cloud. It offers a complete API-driven service for web scraping, automated testing, PDF generation, screenshot capture, and any browser automation tasks your applications require. Built to handle production workloads, Browserless eliminates the complexity of managing browser instances while providing advanced features like session management, queue handling, and resource optimization.
Browserless stands out for its:
- Production-Ready Infrastructure: Built-in queue management, session handling, and resource optimization
- Comprehensive API: REST and WebSocket APIs for all browser automation tasks
- Multiple Browser Support: Chrome, Chromium, and Firefox with various versions
- Advanced Features: Screenshot capture, PDF generation, HTML to image conversion, file downloads
- Resource Management: Automatic memory management, connection pooling, and concurrent request handling
- Developer-Friendly: Simple API design with extensive documentation and debugging tools
- Security: Isolated browser sessions, CORS support, and secure credential handling
- Monitoring: Built-in metrics, health checks, and debugging capabilities
This comprehensive guide walks you through deploying Browserless on Klutch.sh using Docker, including detailed installation steps, Dockerfile configuration, persistent storage setup, environment variables, and production-ready best practices for scalable browser automation.
Prerequisites
Before you begin, ensure you have the following:
- A Klutch.sh account
- A GitHub account with a repository for your Browserless project
- Docker installed locally for testing (optional but recommended)
- Basic understanding of Docker, browser automation, and web APIs
Installation and Setup
Step 1: Create Your Project Directory
First, create a new directory for your Browserless deployment project:
mkdir browserless-klutchcd browserless-klutchgit initStep 2: Create the Dockerfile
Create a Dockerfile in your project root directory. This will define your Browserless container configuration:
FROM ghcr.io/browserless/chromium:latest
# Set working directoryWORKDIR /app
# Create necessary directories for downloads and screenshotsRUN mkdir -p /app/downloads /app/screenshots /app/workspace
# Expose the default Browserless portEXPOSE 3000
# Set default environment variables (override these in Klutch.sh dashboard)ENV PORT=3000ENV CONNECTION_TIMEOUT=60000ENV MAX_CONCURRENT_SESSIONS=10ENV PREBOOT_CHROME=trueENV ENABLE_DEBUGGER=falseENV ENABLE_CORS=true
# Start BrowserlessCMD ["start"]Note: This Dockerfile uses the official Browserless Chromium image from GitHub Container Registry. The image is optimized for production deployments with pre-configured browser binaries and dependencies.
Step 3: Advanced Dockerfile with Custom Configuration
For a production-ready setup with additional customization and monitoring:
FROM ghcr.io/browserless/chromium:latest
# Install additional tools for monitoring and debuggingUSER rootRUN apt-get update && apt-get install -y \ curl \ htop \ vim \ && rm -rf /var/lib/apt/lists/*
# Switch back to browserless userUSER browserless
# Set working directoryWORKDIR /app
# Create necessary directories with proper permissionsRUN mkdir -p /app/downloads /app/screenshots /app/workspace /app/fonts
# Expose Browserless portEXPOSE 3000
# Set production environment variablesENV NODE_ENV=productionENV PORT=3000ENV CONNECTION_TIMEOUT=60000ENV MAX_CONCURRENT_SESSIONS=10ENV PREBOOT_CHROME=trueENV ENABLE_DEBUGGER=falseENV ENABLE_CORS=trueENV MAX_QUEUE_LENGTH=100ENV QUEUE_ALERT_URL=""ENV WORKSPACE_DELETE_EXPIRED=trueENV WORKSPACE_EXPIRE_DAYS=3
# Health check to ensure Browserless is runningHEALTHCHECK --interval=30s --timeout=10s --start-period=60s --retries=3 \ CMD curl -f http://localhost:3000/health || exit 1
# Start Browserless with the default commandCMD ["start"]Step 4: Create a Basic Usage Example
Create a example-usage.js file to demonstrate how to use your Browserless instance:
const puppeteer = require('puppeteer-core');
async function testBrowserless() { const browser = await puppeteer.connect({ browserWSEndpoint: 'ws://example-app.klutch.sh:8000', });
const page = await browser.newPage(); await page.goto('https://example.com');
// Take a screenshot await page.screenshot({ path: 'example.png' });
// Get page title const title = await page.title(); console.log('Page title:', title);
// Generate PDF await page.pdf({ path: 'example.pdf', format: 'A4' });
await browser.close();}
testBrowserless().catch(console.error);Step 5: Create Environment Configuration
Create a .env.example file to document the required environment variables:
# Browserless Core ConfigurationPORT=3000CONNECTION_TIMEOUT=60000MAX_CONCURRENT_SESSIONS=10PREBOOT_CHROME=true
# Queue ManagementMAX_QUEUE_LENGTH=100QUEUE_ALERT_URL=
# Security SettingsTOKEN=your-secure-token-hereENABLE_CORS=trueENABLE_DEBUGGER=false
# Workspace ConfigurationWORKSPACE_DELETE_EXPIRED=trueWORKSPACE_EXPIRE_DAYS=3
# Resource LimitsMAX_CPU_PERCENT=100MAX_MEMORY_PERCENT=100
# Feature FlagsENABLE_API_GET=trueENABLE_HEAP_DUMP=falseENABLE_DEBUG_VIEWER=false
# Custom Chrome Flags (optional)CHROME_REFRESH_TIME=3600000DEFAULT_BLOCK_ADS=falseDEFAULT_HEADLESS=trueDEFAULT_IGNORE_HTTPS_ERRORS=falseDEFAULT_IGNORE_DEFAULT_ARGS=falseSecurity Note: Never commit actual tokens or sensitive data to your repository. Use environment variables in the Klutch.sh dashboard.
Step 6: Test Locally (Optional)
Before deploying to Klutch.sh, you can test your Browserless setup locally:
# Build the Docker imagedocker build -t my-browserless .
# Run the containerdocker run -d \ --name browserless-test \ -p 3000:3000 \ -e TOKEN=test-token-123 \ -e MAX_CONCURRENT_SESSIONS=5 \ my-browserless
# View logsdocker logs -f browserless-test
# Test the health endpointcurl http://localhost:3000/health
# Test with Puppeteer (requires Node.js and puppeteer-core)node example-usage.js
# Stop and remove the test container when donedocker stop browserless-testdocker rm browserless-testStep 7: Create API Testing Script
Create a test-api.sh file to test various Browserless API endpoints:
#!/bin/bash
# Set your Browserless URLBROWSERLESS_URL="https://example-app.klutch.sh"TOKEN="your-token-here"
echo "Testing Browserless API endpoints..."
# Health checkecho "1. Health Check:"curl -s "${BROWSERLESS_URL}/health"echo -e "\n"
# Get statsecho "2. Get Stats:"curl -s "${BROWSERLESS_URL}/stats?token=${TOKEN}"echo -e "\n"
# Screenshot APIecho "3. Screenshot API:"curl -X POST "${BROWSERLESS_URL}/screenshot?token=${TOKEN}" \ -H "Content-Type: application/json" \ -d '{"url": "https://example.com"}' \ --output screenshot.pngecho "Screenshot saved to screenshot.png"echo -e "\n"
# PDF APIecho "4. PDF API:"curl -X POST "${BROWSERLESS_URL}/pdf?token=${TOKEN}" \ -H "Content-Type: application/json" \ -d '{"url": "https://example.com"}' \ --output document.pdfecho "PDF saved to document.pdf"echo -e "\n"
# Content APIecho "5. Content API:"curl -X POST "${BROWSERLESS_URL}/content?token=${TOKEN}" \ -H "Content-Type: application/json" \ -d '{"url": "https://example.com"}'echo -e "\n"
echo "API tests complete!"Make the script executable:
chmod +x test-api.shStep 8: Create Documentation
Create a README.md file with usage instructions:
# Browserless Deployment on Klutch.sh
This repository contains the configuration for deploying Browserless headless browser automation platform on Klutch.sh.
## What is Browserless?
Browserless provides a complete solution for running headless Chrome/Chromium browsers in the cloud with a simple REST API.
## Features
- Screenshot and PDF generation- Web scraping and data extraction- Automated testing and monitoring- File downloads and uploads- Custom JavaScript execution- Session management- Queue handling
## Usage Examples
### Using Puppeteer
\`\`\`javascriptconst puppeteer = require('puppeteer-core');
const browser = await puppeteer.connect({ browserWSEndpoint: 'ws://example-app.klutch.sh:8000',});\`\`\`
### Using REST API
\`\`\`bash# Take a screenshotcurl -X POST https://example-app.klutch.sh/screenshot?token=YOUR_TOKEN \ -H "Content-Type: application/json" \ -d '{"url": "https://example.com"}' \ --output screenshot.png
# Generate PDFcurl -X POST https://example-app.klutch.sh/pdf?token=YOUR_TOKEN \ -H "Content-Type: application/json" \ -d '{"url": "https://example.com"}' \ --output document.pdf
# Get page contentcurl -X POST https://example-app.klutch.sh/content?token=YOUR_TOKEN \ -H "Content-Type: application/json" \ -d '{"url": "https://example.com"}'\`\`\`
## API Documentation
Full API documentation is available at:- https://example-app.klutch.sh/docs (when deployed)- https://docs.browserless.io/
## Configuration
See `.env.example` for all available configuration options.Step 9: Push to GitHub
Commit your Dockerfile and configuration files to your GitHub repository:
git add Dockerfile .env.example README.md example-usage.js test-api.shgit commit -m "Add Browserless Dockerfile and configuration"git remote add origin https://github.com/yourusername/browserless-klutch.gitgit push -u origin mainDeploying to Klutch.sh
Now that your Browserless project is ready and pushed to GitHub, follow these steps to deploy it on Klutch.sh with persistent storage.
Deployment Steps
-
Log in to Klutch.sh
Navigate to klutch.sh/app and sign in to your account.
-
Create a New Project
Go to Create Project and give your project a meaningful name (e.g., “Browserless Automation”).
-
Create a New App
Navigate to Create App and configure the following settings:
-
Select Your Repository
- Choose GitHub as your Git source
- Select the repository containing your Dockerfile
- Choose the branch you want to deploy (usually
mainormaster)
-
Configure Traffic Type
- Traffic Type: Select TCP (Browserless uses WebSocket connections for Puppeteer and Playwright)
- Internal Port: Set to
3000(the default port that Browserless listens on)
Note: Browserless requires TCP traffic to support WebSocket connections. Your deployed app will be accessible on port 8000 for external connections, which routes to internal port 3000.
-
Set Environment Variables
Add the following environment variables for your Browserless configuration:
Required Variables:
TOKEN: A secure authentication token (use a strong random string)PORT: Set to3000(must match internal port)
Recommended Variables:
MAX_CONCURRENT_SESSIONS: Maximum concurrent browser sessions (e.g.,10)CONNECTION_TIMEOUT: Connection timeout in milliseconds (e.g.,60000)MAX_QUEUE_LENGTH: Maximum queue length (e.g.,100)PREBOOT_CHROME: Pre-boot Chrome instances for faster startup (true)ENABLE_CORS: Enable CORS for API requests (true)
Optional Variables:
WORKSPACE_DELETE_EXPIRED: Auto-delete expired workspace files (true)WORKSPACE_EXPIRE_DAYS: Days before workspace files expire (e.g.,3)DEFAULT_BLOCK_ADS: Block ads by default (false)ENABLE_DEBUGGER: Enable Chrome DevTools debugger (false)MAX_CPU_PERCENT: Maximum CPU usage percent (e.g.,100)MAX_MEMORY_PERCENT: Maximum memory usage percent (e.g.,100)
Security Note: Always use strong, unique tokens for production deployments. Generate tokens using a secure random string generator.
-
Attach Persistent Volumes
Browserless benefits from persistent storage for downloads, screenshots, and workspace files:
Volume 1 - Downloads:
- Mount Path: Enter
/app/downloads - Size: Choose 5GB-20GB depending on your usage
Volume 2 - Screenshots:
- Mount Path: Enter
/app/screenshots - Size: Choose 5GB-20GB depending on your usage
Volume 3 - Workspace:
- Mount Path: Enter
/app/workspace - Size: Choose 10GB-50GB depending on your usage
Important: Persistent volumes ensure that downloaded files, screenshots, and workspace data persist across deployments and restarts.
- Mount Path: Enter
-
Configure Additional Settings
- Region: Select the region closest to your users for optimal latency
- Compute Resources: Choose CPU and memory based on your workload (minimum 2GB RAM recommended for browser automation)
- Instances: Start with 1 instance (you can scale horizontally later based on traffic)
-
Deploy Your Application
Click “Create” to start the deployment. Klutch.sh will:
- Automatically detect your Dockerfile in the repository root
- Build the Docker image with all dependencies
- Attach the persistent volumes
- Start your Browserless container
- Assign a URL for external access
-
Access Your Browserless Instance
Once deployment is complete, you’ll receive a URL like
example-app.klutch.sh. Your Browserless instance will be accessible via:WebSocket Connection (for Puppeteer/Playwright):
ws://example-app.klutch.sh:8000HTTP API Endpoints:
https://example-app.klutch.sh:8000/screenshothttps://example-app.klutch.sh:8000/pdfhttps://example-app.klutch.sh:8000/contenthttps://example-app.klutch.sh:8000/statsHealth Check:
https://example-app.klutch.sh:8000/health
Using Browserless with Puppeteer
After your Browserless instance is deployed, you can connect to it using Puppeteer:
Installing Puppeteer Core
First, install puppeteer-core in your application (not puppeteer, which includes Chrome):
npm install puppeteer-coreConnecting to Browserless
const puppeteer = require('puppeteer-core');
async function main() { // Connect to your Browserless instance const browser = await puppeteer.connect({ browserWSEndpoint: 'ws://example-app.klutch.sh:8000?token=YOUR_TOKEN', });
// Create a new page const page = await browser.newPage();
// Navigate to a website await page.goto('https://example.com', { waitUntil: 'networkidle2', });
// Take a screenshot const screenshot = await page.screenshot({ encoding: 'base64' }); console.log('Screenshot captured');
// Get page content const content = await page.content(); console.log('Page content length:', content.length);
// Extract data const title = await page.evaluate(() => document.title); console.log('Page title:', title);
// Close browser await browser.close();}
main().catch(console.error);Advanced Puppeteer Usage
const puppeteer = require('puppeteer-core');
async function advancedUsage() { const browser = await puppeteer.connect({ browserWSEndpoint: 'ws://example-app.klutch.sh:8000?token=YOUR_TOKEN', });
const page = await browser.newPage();
// Set viewport await page.setViewport({ width: 1920, height: 1080 });
// Set user agent await page.setUserAgent('Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36');
// Navigate with timeout await page.goto('https://example.com', { waitUntil: 'networkidle0', timeout: 30000, });
// Wait for specific element await page.waitForSelector('.main-content', { timeout: 10000 });
// Click element await page.click('button#submit');
// Type into input await page.type('input[name="search"]', 'search query');
// Take full page screenshot await page.screenshot({ path: 'fullpage.png', fullPage: true, });
// Generate PDF with custom options await page.pdf({ path: 'document.pdf', format: 'A4', printBackground: true, margin: { top: '20px', right: '20px', bottom: '20px', left: '20px', }, });
// Execute custom JavaScript const data = await page.evaluate(() => { return { title: document.title, url: window.location.href, links: Array.from(document.querySelectorAll('a')).map(a => a.href), }; }); console.log('Extracted data:', data);
await browser.close();}
advancedUsage().catch(console.error);Using Browserless REST API
Browserless provides a comprehensive REST API for browser automation without writing code:
Screenshot API
Capture screenshots of web pages:
# Basic screenshotcurl -X POST https://example-app.klutch.sh:8000/screenshot?token=YOUR_TOKEN \ -H "Content-Type: application/json" \ -d '{"url": "https://example.com"}' \ --output screenshot.png
# Full page screenshot with custom viewportcurl -X POST https://example-app.klutch.sh:8000/screenshot?token=YOUR_TOKEN \ -H "Content-Type: application/json" \ -d '{ "url": "https://example.com", "options": { "fullPage": true, "type": "png" }, "viewport": { "width": 1920, "height": 1080 } }' \ --output fullpage.png
# Screenshot with selectorcurl -X POST https://example-app.klutch.sh:8000/screenshot?token=YOUR_TOKEN \ -H "Content-Type: application/json" \ -d '{ "url": "https://example.com", "selector": ".main-content", "options": { "type": "jpeg", "quality": 90 } }' \ --output element.jpgPDF API
Generate PDFs from web pages:
# Basic PDFcurl -X POST https://example-app.klutch.sh:8000/pdf?token=YOUR_TOKEN \ -H "Content-Type: application/json" \ -d '{"url": "https://example.com"}' \ --output document.pdf
# PDF with custom optionscurl -X POST https://example-app.klutch.sh:8000/pdf?token=YOUR_TOKEN \ -H "Content-Type: application/json" \ -d '{ "url": "https://example.com", "options": { "format": "A4", "printBackground": true, "margin": { "top": "20px", "right": "20px", "bottom": "20px", "left": "20px" } } }' \ --output styled-document.pdfContent API
Extract page content and HTML:
# Get page contentcurl -X POST https://example-app.klutch.sh:8000/content?token=YOUR_TOKEN \ -H "Content-Type: application/json" \ -d '{"url": "https://example.com"}'
# Get content with custom user agentcurl -X POST https://example-app.klutch.sh:8000/content?token=YOUR_TOKEN \ -H "Content-Type: application/json" \ -d '{ "url": "https://example.com", "userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 14_0 like Mac OS X)" }'Stats API
Get Browserless instance statistics:
# Get current statscurl https://example-app.klutch.sh:8000/stats?token=YOUR_TOKEN
# Get metricscurl https://example-app.klutch.sh:8000/metrics?token=YOUR_TOKENFunction API
Execute custom JavaScript in the browser:
curl -X POST https://example-app.klutch.sh:8000/function?token=YOUR_TOKEN \ -H "Content-Type: application/json" \ -d '{ "code": "async ({ page }) => { await page.goto(\"https://example.com\"); const title = await page.title(); return { title }; }" }'Environment Variables Reference
Complete list of Browserless environment variables you can configure in Klutch.sh:
| Variable | Description | Required | Default |
|---|---|---|---|
TOKEN | Authentication token for API access | Yes | None |
PORT | Port for Browserless server | Yes | 3000 |
CONNECTION_TIMEOUT | Connection timeout in milliseconds | No | 60000 |
MAX_CONCURRENT_SESSIONS | Maximum concurrent browser sessions | No | 10 |
PREBOOT_CHROME | Pre-boot Chrome instances | No | true |
ENABLE_CORS | Enable CORS for API requests | No | true |
ENABLE_DEBUGGER | Enable Chrome DevTools debugger | No | false |
MAX_QUEUE_LENGTH | Maximum queue length | No | 100 |
QUEUE_ALERT_URL | Webhook URL for queue alerts | No | None |
WORKSPACE_DELETE_EXPIRED | Auto-delete expired workspace files | No | true |
WORKSPACE_EXPIRE_DAYS | Days before workspace files expire | No | 3 |
MAX_CPU_PERCENT | Maximum CPU usage percent | No | 100 |
MAX_MEMORY_PERCENT | Maximum memory usage percent | No | 100 |
DEFAULT_BLOCK_ADS | Block ads by default | No | false |
DEFAULT_HEADLESS | Run in headless mode | No | true |
DEFAULT_IGNORE_HTTPS_ERRORS | Ignore HTTPS errors | No | false |
ENABLE_API_GET | Enable GET requests for APIs | No | true |
ENABLE_HEAP_DUMP | Enable heap dump endpoint | No | false |
ENABLE_DEBUG_VIEWER | Enable debug viewer | No | false |
CHROME_REFRESH_TIME | Chrome refresh time in milliseconds | No | 3600000 |
Production Best Practices
Security Recommendations
- Strong Tokens: Use a cryptographically secure random string for
TOKEN(minimum 32 characters) - Environment Variables: Store all sensitive credentials as environment variables in Klutch.sh, never in your Dockerfile
- HTTPS Only: Always use HTTPS for REST API calls (Klutch.sh provides this by default)
- Token Protection: Never expose your token in client-side code or public repositories
- Regular Updates: Keep Browserless updated to the latest version for security patches
- Resource Limits: Set appropriate
MAX_CONCURRENT_SESSIONSto prevent resource exhaustion - CORS Configuration: Set
ENABLE_CORSbased on your security requirements
Performance Optimization
- Pre-booting: Enable
PREBOOT_CHROME=trueto reduce cold start times - Session Limits: Configure
MAX_CONCURRENT_SESSIONSbased on available resources - Queue Management: Set
MAX_QUEUE_LENGTHto handle traffic spikes gracefully - Connection Timeout: Adjust
CONNECTION_TIMEOUTbased on your workload - Resource Allocation: Allocate at least 2GB RAM per instance for stable browser operation
- Horizontal Scaling: Scale to multiple instances for high-traffic scenarios
- Workspace Cleanup: Enable
WORKSPACE_DELETE_EXPIRED=trueto manage disk space
Monitoring and Maintenance
Monitor your Browserless deployment for:
- Active Sessions: Track concurrent sessions via
/statsendpoint - Queue Length: Monitor queue depth to identify bottlenecks
- Memory Usage: Browser automation is memory-intensive; monitor RAM usage
- Response Times: Track API response times for performance degradation
- Error Rates: Monitor failed sessions and timeouts
- Disk Usage: Watch workspace and download directory sizes
- Health Status: Use
/healthendpoint for uptime monitoring
Resource Management
- CPU Allocation: Minimum 1 CPU core, recommend 2+ for production
- Memory Allocation: Minimum 2GB RAM, recommend 4GB+ for concurrent sessions
- Disk Space: Allocate sufficient storage for volumes (20GB+ recommended)
- Network Bandwidth: Ensure adequate bandwidth for high-traffic scenarios
- Concurrent Sessions: Start with 10 sessions, adjust based on resource usage
Common Use Cases
Web Scraping
const puppeteer = require('puppeteer-core');
async function scrapeWebsite(url) { const browser = await puppeteer.connect({ browserWSEndpoint: 'ws://example-app.klutch.sh:8000?token=YOUR_TOKEN', });
const page = await browser.newPage(); await page.goto(url, { waitUntil: 'networkidle2' });
// Extract structured data const data = await page.evaluate(() => { const articles = []; document.querySelectorAll('article').forEach(article => { articles.push({ title: article.querySelector('h2')?.textContent, description: article.querySelector('p')?.textContent, link: article.querySelector('a')?.href, }); }); return articles; });
await browser.close(); return data;}Automated Testing
const puppeteer = require('puppeteer-core');
async function testWebsite() { const browser = await puppeteer.connect({ browserWSEndpoint: 'ws://example-app.klutch.sh:8000?token=YOUR_TOKEN', });
const page = await browser.newPage();
// Navigate to the app await page.goto('https://myapp.com/login');
// Fill login form await page.type('#username', 'testuser'); await page.type('#password', 'testpass'); await page.click('button[type="submit"]');
// Wait for navigation await page.waitForNavigation();
// Verify logged in const isLoggedIn = await page.$eval('.user-menu', el => !!el); console.assert(isLoggedIn, 'User should be logged in');
// Take screenshot of dashboard await page.screenshot({ path: 'dashboard.png' });
await browser.close();}Report Generation
const puppeteer = require('puppeteer-core');
async function generateReport(data) { const browser = await puppeteer.connect({ browserWSEndpoint: 'ws://example-app.klutch.sh:8000?token=YOUR_TOKEN', });
const page = await browser.newPage();
// Generate HTML report const html = ` <html> <head> <style> body { font-family: Arial, sans-serif; margin: 40px; } h1 { color: #333; } table { border-collapse: collapse; width: 100%; } th, td { border: 1px solid #ddd; padding: 8px; text-align: left; } th { background-color: #f2f2f2; } </style> </head> <body> <h1>Monthly Report</h1> <table> <tr><th>Metric</th><th>Value</th></tr> ${data.map(item => `<tr><td>${item.name}</td><td>${item.value}</td></tr>`).join('')} </table> </body> </html> `;
await page.setContent(html);
// Generate PDF report await page.pdf({ path: 'monthly-report.pdf', format: 'A4', printBackground: true, margin: { top: '20px', right: '20px', bottom: '20px', left: '20px' }, });
await browser.close();}Troubleshooting
Cannot Connect to Browserless
- Verify your app is running in the Klutch.sh dashboard
- Check that the internal port is set to 3000
- Ensure TCP traffic type is selected
- Verify you’re connecting to port 8000 externally
- Check that your TOKEN is correct and included in the connection string
- Review application logs for startup errors
WebSocket Connection Fails
- Ensure you’re using TCP traffic type (not HTTP)
- Verify the WebSocket endpoint:
ws://example-app.klutch.sh:8000 - Check that the token is included in the connection URL
- Test with curl first:
curl https://example-app.klutch.sh:8000/health - Review firewall or network policies that might block WebSocket connections
Browser Sessions Timeout
- Increase
CONNECTION_TIMEOUTenvironment variable - Check
MAX_CONCURRENT_SESSIONSisn’t exceeded - Monitor queue length via
/statsendpoint - Increase compute resources if sessions are slow
- Check for memory leaks in your automation scripts
High Memory Usage
- Reduce
MAX_CONCURRENT_SESSIONSto match available resources - Enable
WORKSPACE_DELETE_EXPIRED=trueto cleanup old files - Ensure browser instances are properly closed in your code
- Monitor memory usage in Klutch.sh dashboard
- Consider scaling horizontally with multiple instances
Persistent Storage Issues
- Confirm persistent volumes are correctly attached
- Check volume mount paths:
/app/downloads,/app/screenshots,/app/workspace - Verify sufficient disk space is allocated to volumes
- Check file permissions in the mounted directories
- Review logs for disk I/O errors
Performance Issues
- Monitor CPU and memory usage in Klutch.sh dashboard
- Check active sessions via
/statsendpoint - Reduce
MAX_CONCURRENT_SESSIONSif resources are constrained - Enable
PREBOOT_CHROME=truefor faster cold starts - Consider increasing compute resources or scaling horizontally
- Profile your automation scripts for inefficiencies
API Errors
- Verify the API endpoint URL is correct
- Check that the TOKEN is valid and included in requests
- Review API request payload format in the Browserless documentation
- Check response status codes and error messages
- Test with simple requests first (e.g.,
/health)
Scaling Browserless
Vertical Scaling
Increase resources for a single instance:
- CPU: Scale to 2-4 cores for better concurrent session handling
- Memory: Increase to 4GB-8GB for more concurrent sessions
- Disk: Expand volume sizes as workspace grows
- Sessions: Increase
MAX_CONCURRENT_SESSIONSproportionally to resources
Horizontal Scaling
Deploy multiple Browserless instances for high availability:
- Create multiple app instances in Klutch.sh
- Use a load balancer to distribute traffic
- Configure session affinity if needed
- Share persistent storage across instances (consider object storage)
- Monitor aggregate metrics across all instances
Auto-Scaling Considerations
- Monitor queue length and active sessions
- Scale up when
MAX_QUEUE_LENGTHis frequently reached - Scale down during low-traffic periods
- Use health checks for automatic failover
- Implement retry logic in client applications
Upgrading Browserless
To upgrade Browserless to a new version:
-
Update the version tag in your Dockerfile:
FROM ghcr.io/browserless/chromium:v2.20.0 -
Review the release notes for breaking changes
-
Test the new version locally before deploying:
Terminal window docker build -t my-browserless:v2.20.0 .docker run -d -p 3000:3000 -e TOKEN=test my-browserless:v2.20.0 -
Commit and push the changes to GitHub:
Terminal window git add Dockerfilegit commit -m "Upgrade Browserless to version 2.20.0"git push -
Klutch.sh will automatically rebuild and redeploy your application
-
Your data will be preserved because it’s stored in persistent volumes
Additional Resources
- Klutch.sh Documentation
- Official Browserless Documentation
- Browserless GitHub Repository
- Puppeteer Documentation
- Playwright Documentation
- Klutch.sh Volumes Guide
- Klutch.sh Networking Guide
- Browserless Docker Images
Conclusion
Deploying Browserless to Klutch.sh with Docker provides a powerful, scalable solution for headless browser automation with persistent storage, comprehensive API access, and production-ready features. By following this guide, you’ve set up a robust Browserless instance with proper configuration, security settings, and resource management. Your browser automation platform is now ready to handle web scraping, automated testing, PDF generation, screenshot capture, and any other browser automation tasks your applications require, all with the reliability and scalability of Klutch.sh’s infrastructure.