Skip to content

PC Proxy Setup

Purpose: Offload upload/download bandwidth from Render to local PCs via Cloudflare Tunnel, reducing Render bandwidth costs to near-zero.

Architecture Overview

graph LR
    Browser -->|"auth + metadata (tiny JSON)"| Render
    Browser -->|"file bytes (10MB chunks)"| PC["PC Proxy (Cloudflare Tunnel)"]
    PC -->|"upload"| GDrive["Google Drive API"]
    PC -->|"upload"| Wasabi["Wasabi S3"]
    PC -->|"download stream"| Browser
    Render -.->|"fallback if PC down"| Browser

Key principle: Render handles only authentication, database operations, and returns metadata. All file bytes flow through the PC proxy. If the PC is down, the frontend automatically falls back to Render — transparent to the user.


Components

Component Location Role
PC Proxy Flask app LenzeyeProxyPC/ (separate repo) Handles file upload/download
/api/proxy-config endpoint proxy_config_routes.py in main repo Tells frontend which PCs are healthy
proxyHelper.js static/upload-app/proxyHelper.js Frontend module for upload proxy routing
proxyDownloadFetch() Inline in DownloadUpload_manager.html Frontend function for download proxy routing

Render Environment Variables

Variable Example Description
PC_PROXY_ENABLED true Master switch. false = everything uses Render as before
PC_PROXY_URLS https://pc1.lenzeye.in,https://pc2.lenzeye.in Comma-separated list of PC proxy URLs (ordered by priority)
PROXY_SHARED_SECRET a-long-random-string-64-chars Shared secret for X-Proxy-Secret header authentication

Kill Switch

Setting PC_PROXY_ENABLED=false immediately routes everything back through Render. No redeployment needed — takes effect in ~30 seconds.


PC Proxy Setup (Per PC)

Prerequisites

  • Windows 10/11 PC (always on, sleep disabled)
  • Internet connection (40+ Mbps upload recommended)
  • A Cloudflare account (free tier works)
  • Two values from the Lenzeye admin: PROXY_SHARED_SECRET and LENZEYE_MASTER_KEY

The fastest way — handles everything automatically:

  1. Copy the LenzeyeProxyPC/ folder to the PC
  2. Right-click setup.batRun as administrator
  3. Follow the on-screen prompts (it will ask for the shared secret and master key)
  4. The script will install Python dependencies, configure .env, install the Windows service, download tools, and set up Cloudflare Tunnel
  5. Tell the admin to add your PC URL to PC_PROXY_URLS on Render

Setup Time

First PC: ~15 minutes. Additional PCs: ~10 minutes.

What You Need Ready

  • PROXY_SHARED_SECRET (from admin)
  • LENZEYE_MASTER_KEY (from admin)
  • Cloudflare account credentials (email + password)
  • A hostname for this PC (e.g. pc1.lenzeye.in)

Option B: Manual Setup

If you prefer to set up each component manually:

Step 1: Install Python

Download and install Python 3.9+ from python.org. Check "Add Python to PATH" during install.

Step 2: Install Dependencies

powershell cd LenzeyeProxyPC pip install -r requirements.txt

Step 3: Configure Environment

Copy .env.example to .env and fill in:

```ini

Authentication

PROXY_SHARED_SECRET=same-secret-as-render-env-var

Wasabi S3 (pre-filled, no changes needed)

WASABI_ENDPOINT=https://s3.ap-southeast-1.wasabisys.com WASABI_ACCESS_KEY=your-wasabi-access-key WASABI_SECRET_KEY=your-wasabi-secret-key WASABI_BUCKET=your-bucket-name

Encryption (must match Render's LENZEYE_MASTER_KEY)

LENZEYE_MASTER_KEY=your-base64-or-hex-master-key

Render server URL (for HMAC forwarding on encrypted GDrive uploads)

RENDER_BASE_URL=https://www.lenzeye.in

Server

PORT=5050 THREADS=8 ```

Security

The .env file contains production secrets. Never commit it to git. The .gitignore already excludes it.

Step 4: Set Up Cloudflare Tunnel

Run the setup script as Administrator:

powershell .\setup_cloudflare_tunnel.bat

This will:

  1. Download cloudflared.exe if not present
  2. Authenticate with Cloudflare (cloudflared tunnel login)
  3. Create a tunnel named lenzeye-proxy
  4. Route it to localhost:5050
  5. Create a DNS entry (e.g., pc1.lenzeye.in)
  6. Install cloudflared as a Windows service

After setup, your PC will be accessible at https://pc1.lenzeye.in.

Step 5: Install as Windows Service

```powershell

Run as Administrator

.\install_service.bat ```

This uses NSSM to register the Flask app as a Windows service that:

  • Starts automatically on boot
  • Runs without any user logged in
  • Restarts automatically on crash
  • Logs output to logs/ folder

Step 6: Verify

```powershell

Check service is running

nssm status LenzeyeProxyPC

Test health endpoint

curl https://pc1.lenzeye.in/health ```

Expected response: json {"status": "ok", "timestamp": "2026-07-14T06:00:00Z"}

Step 7: Register on Render

Add the PC URL to Render's PC_PROXY_URLS env var:

PC_PROXY_URLS=https://pc1.lenzeye.in,https://pc2.lenzeye.in


How Failover Works

Upload Flow

  1. Browser calls GET /api/proxy-config → gets { enabled: true, proxies: ["https://pc1...", "https://pc2..."], secret: "..." }
  2. For each chunk upload, proxyHelper.js tries PC1 first
  3. If PC1 returns 5xx or is unreachable → tries PC2
  4. If all PCs fail → falls back to Render (same URL, no proxy header)
  5. Failed PCs get a 60-second cooldown before retrying

Download Flow

  1. Browser fetches file metadata from Render (tiny JSON)
  2. Render returns a download URL (presigned Wasabi URL or relative GDrive proxy path)
  3. proxyDownloadFetch() checks if URL is relative (GDrive/encrypted) or absolute (Wasabi)
  4. Relative URLs → route through PC proxy with same failover logic
  5. Absolute Wasabi URLs → direct fetch (no proxy needed, zero Render bandwidth)

What Gets Proxied

Route Proxied? Why
Wasabi encrypted upload-part ✅ Yes 10MB chunk goes through server for encryption
GDrive upload-part ✅ Yes 10MB chunk goes through server to Google API
GDrive encrypted upload-part ✅ Yes 10MB chunk encrypted + sent to Google
Wasabi unencrypted upload-part ❌ No Uses presigned URL (browser → Wasabi directly)
GDrive proxy download ✅ Yes Server streams from Google Drive
Encrypted stream-decrypt ❌ No Needs DB for OTP/token/key verification — stays on Render
Wasabi direct download ❌ No Presigned URL (browser → Wasabi directly)

Monitoring & Troubleshooting

Health Check

The /api/proxy-config endpoint on Render pings each PC's /health endpoint every 30 seconds (cached). Unhealthy PCs are removed from the list returned to the frontend.

Logs

On the PC, check: ```powershell

Service logs

type C:\LenzeyeProxyPC\logs\stdout.log type C:\LenzeyeProxyPC\logs\stderr.log

Cloudflare tunnel logs

cloudflared tunnel info lenzeye-proxy ```

Common Issues

Issue Solution
PC offline / tunnel down Frontend auto-falls back to Render. No user impact.
X-Proxy-Secret mismatch Check .env on PC matches PROXY_SHARED_SECRET on Render
GDrive downloads failing Check PROXY_SHARED_SECRET matches on both Render and PC (used to encrypt/decrypt proxy_token)
High RAM on PC Check concurrent uploads; reduce THREADS in .env
Slow uploads Check internet speed; consider adding a second PC

GDrive Download Security (proxy_token)

GDrive downloads require a Google access token. To avoid exposing the raw token to the browser:

  1. Render generates the download URL and encrypts the access_token using PROXY_SHARED_SECRET (AES-256-GCM)
  2. The encrypted blob (proxy_token) is embedded in the download URL as a query param
  3. Browser sees only the opaque blob — cannot extract the real token
  4. PC Proxy decrypts the blob using its copy of PROXY_SHARED_SECRET and uses the real token to call Google Drive API
  5. If the token expires (1 hour), the next download request generates a fresh encrypted blob

This means even if someone intercepts the download URL, the proxy_token is useless without PROXY_SHARED_SECRET.

For GDrive uploads, no token is needed — Google's resumable session URI is self-authenticated for 1 week.


Adding a New PC

  1. Set up the new PC following Steps 1-5 above
  2. Use a different tunnel DNS name (e.g., pc2.lenzeye.in)
  3. Append it to PC_PROXY_URLS on Render: https://pc1.lenzeye.in,https://pc2.lenzeye.in
  4. The frontend will automatically try PCs in order (left = highest priority)

Removing a PC

  1. Remove its URL from PC_PROXY_URLS on Render
  2. Optionally stop the service: nssm stop LenzeyeProxyPC
  3. Optionally remove the tunnel: cloudflared tunnel delete lenzeye-proxy

Cost Savings

Before After
All upload/download bytes through Render ($15/100GB) Only auth + metadata through Render (~0.1% of bytes)
~500GB/month = ~$75/month bandwidth ~$0.10/month bandwidth

The PC proxy uses your home internet (already paid for) + Cloudflare Tunnel (free tier, unlimited bandwidth).