# Running Chrome Browser Headless from the Cloud
The LinkedIn automation system uses `puppeteer-core` which connects to Chrome via CDP (Chrome DevTools Protocol). This means you can connect to **any** Chrome instance with remote debugging enabled, whether local or cloud-based.
## 🎯 Solution Options
### Option 1: Browserless.io (Recommended - Easiest)
**Browserless.io** provides managed headless Chrome instances in the cloud.
1. **Sign up**: https://www.browserless.io/
2. **Get your token** from the dashboard
3. **CDP URL format**: `https://production-sfo.browserless.io/chrome?token=YOUR_TOKEN`
4. **Use in API**:
```bash
curl -X POST "https://linkedin-mcp-mocha.vercel.app/api/browser/connect" \
-H "Content-Type: application/json" \
-d '{"cdp_url": "https://production-sfo.browserless.io/chrome?token=YOUR_TOKEN"}'
```
**Pricing**:
- Free tier: 6 hours/month
- Paid: From $75/month
---
### Option 2: Self-Hosted Browserless (Open Source)
Run your own Browserless instance on a cloud VM.
**On AWS EC2, Google Cloud, or Azure VM:**
```bash
# Install Docker
sudo apt-get update && sudo apt-get install -y docker.io
# Run Browserless
docker run -p 3000:3000 \
-e CONNECTION_TIMEOUT=60000 \
-e MAX_CONCURRENT_SESSIONS=10 \
browserless/chrome:latest
# Access at: http://YOUR_VM_IP:3000
```
**Environment Variables:**
```env
CDP_URL=http://YOUR_VM_IP:3000
# Or for WebSocket: ws://YOUR_VM_IP:3000
```
**Update Vercel:**
```env
CDP_URL=http://YOUR_VM_IP:3000
```
---
### Option 3: Playwright/Puppeteer on Cloud Run / AWS Lambda
**For Google Cloud Run:**
```javascript
// cloud-browser-server.js
import express from 'express';
import puppeteer from 'puppeteer';
const app = express();
app.get('/health', async (req, res) => {
try {
const browser = await puppeteer.launch({
headless: true,
args: ['--no-sandbox', '--disable-setuid-sandbox']
});
await browser.close();
res.json({ status: 'ok' });
} catch (error) {
res.status(500).json({ error: error.message });
}
});
// Start Chrome with remote debugging
async function startChrome() {
const browser = await puppeteer.launch({
headless: true,
args: [
'--remote-debugging-port=9222',
'--no-sandbox',
'--disable-setuid-sandbox',
'--disable-dev-shm-usage'
]
});
return browser;
}
const PORT = process.env.PORT || 9222;
app.listen(PORT);
```
**Dockerfile:**
```dockerfile
FROM ghcr.io/puppeteer/puppeteer:latest
WORKDIR /app
COPY package.json .
RUN npm install
COPY . .
EXPOSE 9222
CMD ["node", "cloud-browser-server.js"]
```
**Deploy to Cloud Run:**
```bash
gcloud run deploy chrome-browser \
--source . \
--port 9222 \
--allow-unauthenticated \
--memory 2Gi \
--cpu 2
```
---
### Option 4: AWS ECS/Fargate with Chrome
**Dockerfile:**
```dockerfile
FROM puppeteer/puppeteer:latest
# Install Chrome with remote debugging
RUN apt-get update && apt-get install -y \
google-chrome-stable \
&& rm -rf /var/lib/apt/lists/*
# Expose CDP port
EXPOSE 9222
# Start Chrome with remote debugging
CMD ["google-chrome", \
"--headless", \
"--remote-debugging-port=9222", \
"--no-sandbox", \
"--disable-setuid-sandbox", \
"--disable-dev-shm-usage", \
"--disable-gpu"]
```
**ECS Task Definition:**
```json
{
"family": "chrome-headless",
"containerDefinitions": [{
"name": "chrome",
"image": "YOUR_ECR_REPO/chrome-headless:latest",
"portMappings": [{
"containerPort": 9222,
"protocol": "tcp"
}],
"memory": 2048,
"cpu": 1024
}]
}
```
---
### Option 5: Bright Data / ScraperAPI (Managed Service)
**Bright Data (formerly Luminati):**
- Managed residential proxies + browser automation
- Pricing: Custom
- URL: https://brightdata.com/
**ScraperAPI:**
- Scraping + browser automation service
- Pricing: From $49/month
- URL: https://www.scraperapi.com/
---
### Option 6: Railway / Render / Fly.io (Easiest PaaS)
**Railway:**
```bash
# Install Railway CLI
npm i -g @railway/cli
# Deploy
railway init
railway up
```
**Add to Railway:**
```env
CDP_URL=http://your-app.railway.app:9222
```
---
## 🚀 Recommended: Browserless.io (Quick Start)
1. **Sign up**: https://www.browserless.io/
2. **Get token** from dashboard
3. **Set environment variable in Vercel**:
```env
CDP_URL=http://chrome.browserless.io?token=YOUR_TOKEN
```
4. **Or pass dynamically in API calls**:
```bash
curl -X POST "https://linkedin-mcp-mocha.vercel.app/api/browser/connect" \
-H "Content-Type: application/json" \
-d '{"cdp_url": "http://chrome.browserless.io?token=YOUR_TOKEN"}'
```
---
## 📝 Update Code to Support Both Local and Cloud
The current code already supports this! You just need to:
1. **For Vercel (Cloud)**:
```env
CDP_URL=https://production-sfo.browserless.io/chrome?token=YOUR_TOKEN
```
2. **For Local Development**:
```env
CDP_URL=http://localhost:9222
```
3. **Make it configurable** - Update `http-server.js`:
```javascript
app.post('/api/browser/connect', async (req, res) => {
try {
const { cdp_url } = req.body;
// Use provided CDP URL or default from environment
const cdpUrl = cdp_url || process.env.CDP_URL;
if (!cdpUrl) {
return res.status(400).json({
success: false,
error: 'cdp_url is required (or set CDP_URL env variable)'
});
}
const result = await linkedinBot.connect(cdpUrl);
res.json(result);
} catch (error) {
res.status(500).json({ success: false, error: error.message });
}
});
```
---
## 🔧 Testing Cloud Browser Connection
```bash
# Test Browserless.io connection
curl -X POST "https://linkedin-mcp-mocha.vercel.app/api/browser/connect" \
-H "Content-Type: application/json" \
-d '{
"cdp_url": "https://production-sfo.browserless.io/chrome?token=YOUR_TOKEN"
}' | python -m json.tool
```
---
## 💰 Cost Comparison
| Solution | Setup Time | Monthly Cost | Scalability |
|----------|-----------|--------------|-------------|
| Browserless.io | 5 min | $75+ | High |
| Self-Hosted Browserless | 30 min | $20-50 (VM) | Medium |
| Cloud Run / ECS | 1 hour | Pay-per-use | High |
| Railway / Render | 10 min | $5-20 | Low-Medium |
---
## ⚠️ Important Notes
1. **LinkedIn Detection**: Use stealth plugins (already implemented)
2. **Rate Limiting**: Implement delays between requests
3. **Session Management**: Keep browser sessions alive
4. **Costs**: Cloud browsers can be expensive at scale
5. **Security**: Don't expose browser endpoints publicly
---
## 🎯 Quick Start with Browserless.io
```bash
# 1. Sign up at browserless.io
# 2. Get your token (from dashboard)
# 3. Test connection
curl -X POST "YOUR_API_URL/api/browser/connect" \
-H "Content-Type: application/json" \
-d '{"cdp_url": "https://production-sfo.browserless.io/chrome?token=YOUR_TOKEN"}'
# 4. If successful, set in Vercel
# CDP_URL=https://production-sfo.browserless.io/chrome?token=YOUR_TOKEN
```
**The code is already compatible! Just change the CDP URL from localhost to your cloud browser service!** ✅