FRP Proxy Setup Guide
February 22, 2026 · View on GitHub
This guide explains how to configure the backend to use your DO server as a lightweight proxy while doing all heavy LLM processing on your desktop.
Architecture Overview
┌─────────────┐ ┌──────────────┐ ┌─────────────┐
│ │ HTTP │ │ FRP │ │
│ Frontend ├────────►│ DO Server ├────────►│ Desktop │
│ │ │ (Proxy) │ Tunnel │ (Processing)│
└─────────────┘ └──────────────┘ └─────────────┘
│ │
│ │
▼ ▼
┌──────────────┐ ┌──────────────┐
│ Turso DB │ │ Gemini CLI │
│ AWS S3 │ │ LLM Models │
└──────────────┘ └──────────────┘
Components
-
DO Server (YOUR_SERVER_IP)
- Main Express backend (port 3000)
- FRP Server (port 7000)
- Handles: Database, S3, routing, rate limiting
- Does NOT handle: LLM processing, PDF analysis, code analysis
-
Desktop (Your Local Machine)
- FRP Client (connects to DO server)
- Processing Server (port 3001)
- Handles: All LLM processing, Gemini CLI, code analysis
-
FRP Tunnel
- Secure TCP tunnel between DO server and desktop
- Forwards port 7001 on DO server to port 3001 on desktop
- Encrypted communication
Prerequisites
On DO Server
- Node.js 18+ installed
- Backend deployed
- Ports 3000, 7000, 7001, 7500 open in firewall
On Desktop
- Node.js 18+ installed
- Gemini CLI installed
- LLM API keys configured
- Stable internet connection
- Git installed (for code analysis)
Installation Steps
Step 1: Install FRP
We've provided an automated script to install FRP:
cd backend
./scripts/setup-frp.sh
Follow the prompts to install either:
- Option 1: FRP Server (for DO server)
- Option 2: FRP Client (for desktop)
Or manually download from: https://github.com/fatedier/frp/releases
Step 2: Configure DO Server
2.1 Update .env file
Add to your DO server's .env:
# Enable processing proxy
PROCESSING_ENABLED=true
PROCESSING_DESKTOP_URL=http://127.0.0.1:7001
PROCESSING_TIMEOUT=300000
# Optional: Disable local reader to save resources
READER_ENABLED=false
2.2 Configure FRP Server
Edit /etc/frp/frps.toml:
bindPort = 7000
auth.method = "token"
auth.token = "YOUR_SECURE_TOKEN_HERE" # Change this!
webServer.addr = "0.0.0.0"
webServer.port = 7500
webServer.user = "admin"
webServer.password = "YOUR_DASHBOARD_PASSWORD" # Change this!
log.to = "/var/log/frp/frps.log"
log.level = "info"
2.3 Start FRP Server
sudo systemctl start frps
sudo systemctl enable frps
sudo systemctl status frps
2.4 Update Firewall
# Allow FRP control port
sudo ufw allow 7000/tcp
# Allow FRP dashboard (optional, for monitoring)
sudo ufw allow 7500/tcp
# Allow FRP data port
sudo ufw allow 7001/tcp
Step 3: Configure Desktop
3.1 Setup Environment
Create .env in backend directory:
# Copy from DO server
TURSO_DATABASE_URL=your_turso_url
TURSO_AUTH_TOKEN=your_turso_token
AWS_ACCESS_KEY_ID=your_aws_key
AWS_SECRET_ACCESS_KEY=your_aws_secret
AWS_REGION=us-east-1
AWS_S3_BUCKET=auto-reader-documents
# LLM API Keys (configure at least one)
GEMINI_API_KEY=your_gemini_key
ANTHROPIC_API_KEY=your_anthropic_key
# Mathpix (for large PDFs)
MATHPIX_APP_ID=your_app_id
MATHPIX_APP_KEY=your_app_key
# Processing server port
PROCESSING_PORT=3001
3.2 Configure FRP Client
Edit backend/frpc-local.toml:
serverAddr = "YOUR_SERVER_IP" # Your DO server IP
serverPort = 7000
auth.method = "token"
auth.token = "YOUR_SECURE_TOKEN_HERE" # MUST match server!
[[proxies]]
name = "llm-processing"
type = "tcp"
localIP = "127.0.0.1"
localPort = 3001
remotePort = 7001
3.3 Install Dependencies
cd backend
npm install
Step 4: Start Services
On Desktop (start in this order):
-
Start FRP Client
cd backend frpc -c frpc-local.tomlYou should see: "login to server success"
-
Start Processing Server
cd backend node processing-server.jsYou should see: "Desktop Processing Server running on port 3001"
On DO Server:
- Restart Backend
cd backend pm2 restart all
Step 5: Verify Setup
Check FRP Connection
# On DO server - check FRP logs
sudo journalctl -u frps -f
# On desktop - check FRP client logs
tail -f frpc.log
Check Processing Connection
# On DO server - test connection to desktop
curl http://127.0.0.1:7001/health
# Should return:
# {"status":"ok","service":"Desktop Processing Server",...}
Test End-to-End
- Upload a PDF document via frontend
- Request processing
- Check logs:
- DO server should log: "Forwarding to desktop for processing"
- Desktop should log: "Document request: ..."
Monitoring
FRP Dashboard
Access at: http://YOUR_DO_SERVER_IP:7500
- Username: admin
- Password: (what you set in config)
Shows:
- Connected clients
- Active proxies
- Traffic statistics
Application Logs
DO Server:
pm2 logs
Desktop:
# FRP client
tail -f frpc.log
# Processing server
tail -f processing-server.log
Troubleshooting
Desktop Not Connecting
Symptom: DO server can't reach desktop
Check:
-
FRP client running on desktop?
ps aux | grep frpc -
FRP token matches?
- Compare
frps.tomlandfrpc-local.toml
- Compare
-
Firewall blocking port 7000?
telnet YOUR_SERVER_IP 7000
Processing Server Not Responding
Symptom: Requests timeout
Check:
-
Processing server running?
ps aux | grep processing-server -
Test local connection:
curl http://localhost:3001/health -
Gemini CLI available?
which gemini gemini --version
Documents Falling Back to Local Processing
Symptom: "Desktop processing failed, falling back to local"
Possible causes:
- Desktop server crashed
- FRP connection dropped
- Request timeout (default 5 minutes)
Solutions:
- Restart processing server
- Check FRP connection
- Increase timeout in .env:
PROCESSING_TIMEOUT=600000
Performance Tuning
For Faster Processing
-
Increase parallelism (on desktop):
# Start multiple processing servers PROCESSING_PORT=3001 node processing-server.js & PROCESSING_PORT=3002 node processing-server.js &Then configure multiple FRP proxies
-
Use faster models: Update
.env:GEMINI_MODEL=gemini-1.5-flash -
Disable rate limiting (if you control access): Update DO server
.env:RATE_LIMIT_MAX=999999 PAPER_ANALYSIS_MAX=999999
For Cost Optimization
-
Use cheaper models:
GEMINI_MODEL=gemini-1.5-flash # Cheaper than pro -
Set lower page limits:
READER_MAX_PAGE_COUNT=20 # Process fewer pages
Security Considerations
-
Strong FRP Token: Use a long random string
openssl rand -hex 32 -
Firewall Rules: Only allow necessary IPs
# On DO server - only allow your desktop IP sudo ufw allow from YOUR_DESKTOP_IP to any port 7000 -
HTTPS for Frontend: Use SSL certificate
-
Rotate Tokens: Change FRP token periodically
Maintenance
Update FRP
# Download new version
wget https://github.com/fatedier/frp/releases/download/vX.X.X/...
# Extract and replace binaries
sudo systemctl stop frps # or stop frpc
sudo cp frps /usr/local/bin/
sudo systemctl start frps
Backup Configuration
# On DO server
sudo cp /etc/frp/frps.toml /backup/
# On desktop
cp frpc-local.toml /backup/
Alternative: Running Desktop Server as Daemon
Using PM2 (Recommended)
# Install PM2
npm install -g pm2
# Start processing server
pm2 start processing-server.js --name "desktop-processing"
# Start FRP client
pm2 start "frpc -c frpc-local.toml" --name "frp-client"
# Save configuration
pm2 save
pm2 startup
Using systemd
Create /etc/systemd/system/processing-server.service:
[Unit]
Description=Desktop Processing Server
After=network.target
[Service]
Type=simple
User=YOUR_USER
WorkingDirectory=/path/to/backend
ExecStart=/usr/bin/node processing-server.js
Restart=on-failure
[Install]
WantedBy=multi-user.target
Then:
sudo systemctl enable processing-server
sudo systemctl start processing-server
Cost Comparison
Before (All on DO Server)
- 1 CPU droplet: Struggles with LLM processing
- Frequent timeouts
- Need to upgrade: $24+/month
After (Proxy Setup)
- Basic DO droplet: $6/month (just proxy)
- Desktop: Free (you already have it)
- Better performance with desktop GPU/CPU
- Pay only for API calls
Questions?
- Check logs first: Both DO server and desktop
- Verify FRP connection: Dashboard at port 7500
- Test independently:
curl http://127.0.0.1:7001/health
Summary
✅ DO Server: Lightweight proxy ($6/month) ✅ Desktop: Heavy processing (free) ✅ FRP: Secure tunnel between them ✅ Fallback: Local processing if desktop unavailable ✅ Scalable: Add more desktop workers as needed