Skip to main content

cliproxyapi-cloudflare-stack

Self-hosted OpenAI-compatible LLM API gateway with multi-credential pooling, Cloudflare email workers, and tunnel exposure

الانتقال إلى التثبيت

معلومات المصدر

المستودع
reason-machines/devtools-skills
آخر نشاط في المصدر
٣٠ يوليو ٢٠٢٦ في ٠٤:٣٤
لغة SKILL.md المكتشفة
الإنجليزية
النجوم
٤
التفرعات
٠

خيارات التثبيت

يُحدَّد Prompt الذي يراجع المصدر أولًا بشكل افتراضي. يمكنك التبديل إلى أمر مباشر أو تنزيل نسخة محلية.

مراجعة ملفات المصدر

اقرأ SKILL.md وأي ملفات مرافقة يعرضها SkillsMP قبل أن تقرر التثبيت.

عرض SKILL.md

SKILL.md
تعليمات المصدر · معاينة للقراءة فقط
name
cliproxyapi-cloudflare-stack
description
Self-hosted OpenAI-compatible LLM API gateway with multi-credential pooling, Cloudflare email workers, and tunnel exposure
triggers
["set up a self-hosted OpenAI API gateway","deploy CLIProxyAPI with Cloudflare tunnel","configure multi-credential LLM proxy","create automated email credential system","expose internal API gateway with cloudflared","manage multiple LLM credentials with failover","build OpenAI-compatible proxy on Cloudflare","set up Grok API credential rotation"]
# CLIProxyAPI Cloudflare Stack > Skill by [ara.so](https://ara.so) — Devtools Skills collection. ## What It Does This project provides a complete self-hosted stack for running an OpenAI-compatible LLM API gateway with: - **CLIProxyAPI**: Multi-credential pooling with hot-reload and automatic failover - **Cloudflare Worker + D1**: Programmatic email receiving for credential verification - **Cloudflare Tunnel**: Zero-port-forwarding HTTPS exposure of internal gateway - **Unified Interface**: Single `/v1/*` endpoint compatible with OpenAI SDK Use case: Run your own LLM API proxy without sharing credentials with third-party services, supporting multiple provider accounts with automatic rotation. ## Architecture Overview ``` [Client] ↓ HTTPS [Cloudflare Tunnel] → public domain ↓ [CLIProxyAPI Gateway] → localhost:5000 ↓ [Multiple LLM Providers] (Grok, OpenAI, etc.) [Email] → Cloudflare Email Routing → Worker → D1 Database ``` ## Installation ### Prerequisites - Cloudflare account with domain - VM or server with Docker (for CLIProxyAPI) - Node.js 18+ (for Wrangler CLI) - `cloudflared` binary ### 1. Deploy CLIProxyAPI Gateway ```bash # Clone the repository git clone https://github.com/xsser/cliproxyapi-cloudflare-stack.git cd cliproxyapi-cloudflare-stack # Deploy to VM (Ubuntu/Debian) bash scripts/deploy_vm.sh # The script will: # - Install Docker if needed # - Pull CLIProxyAPI image # - Generate API key (sk-xxxxx) # - Create auth directory # - Start container on port 5000 ``` **Expected output:** ``` ✓ CLIProxyAPI deployed ✓ API Key: sk-1234567890abcdef ✓ Auth directory: /opt/cpa/auth ✓ Service running on localhost:5000 ``` Save the `sk-` key — this is your gateway authentication token. ### 2. Set Up Email Worker ```bash # Install Wrangler npm install -g wrangler # Login to Cloudflare wrangler login # Copy and configure template cp templates/wrangler.toml.template wrangler.toml # Edit wrangler.toml nano wrangler.toml ``` **wrangler.toml configuration:** ```toml name = "email-receiver" main = "src/index.js" compatibility_date = "2024-01-01" [[d1_databases]] binding = "DB" database_name = "email_codes" database_id = "YOUR_D1_DATABASE_ID" [vars] ALLOWED_DOMAINS = "x.ai,openai.com" ``` **Create D1 database:** ```bash # Create database wrangler d1 create email_codes # Note the database_id from output and update wrangler.toml # Initialize schema wrangler d1 execute email_codes --file=src/schema.sql ``` **Deploy worker:** ```bash wrangler deploy # Output will show: https://email-receiver.<your-account>.workers.dev ``` **Configure Cloudflare Email Routing:** 1. Go to Cloudflare Dashboard → Email Routing 2. Add catch-all route: `*@yourdomain.com` → Worker `email-receiver` 3. Verify domain email routing is enabled ### 3. Add Credentials Credentials are JSON files in the auth directory with provider-specific format. **Example Grok credential (grok_account1.json):** ```json { "provider": "grok", "api_key": "grok-xxxxxxxxxxxxx", "email": "your-email@domain.com", "status": "active", "rate_limit": { "requests_per_minute": 60 } } ``` **Example OpenAI credential (openai_account1.json):** ```json { "provider": "openai", "api_key": "sk-proj-xxxxxxxxxxxxx", "organization_id": "org-xxxxxxxxxxxxx", "status": "active" } ``` **Sync credentials to VM:** ```bash # From local directory SRC=./auth_local VM_HOST=user@yourvm.com bash scripts/sync_credentials.sh # Or directly on VM scp credentials/*.json user@yourvm:/opt/cpa/auth/ ``` CLIProxyAPI hot-reloads credentials automatically (checks every 30s). ### 4. Expose with Cloudflare Tunnel ```bash # Install cloudflared wget https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-amd64.deb sudo dpkg -i cloudflared-linux-amd64.deb # Authenticate cloudflared tunnel login # Create tunnel cloudflared tunnel create cpa-gateway # Note the tunnel ID from output # Copy service template sudo cp templates/cloudflared-cpa.service.template /etc/systemd/system/cloudflared-cpa.service # Edit service file sudo nano /etc/systemd/system/cloudflared-cpa.service ``` **cloudflared-cpa.service configuration:** ```ini [Unit] Description=Cloudflare Tunnel for CPA Gateway After=network.target [Service] Type=simple User=cloudflared ExecStart=/usr/local/bin/cloudflared tunnel --no-autoupdate run --token YOUR_TUNNEL_TOKEN Restart=always RestartSec=5 [Install] WantedBy=multi-user.target ``` **Create tunnel config:** ```bash mkdir -p ~/.cloudflared nano ~/.cloudflared/config.yml ``` **config.yml:** ```yaml tunnel: YOUR_TUNNEL_ID credentials-file: /home/user/.cloudflared/YOUR_TUNNEL_ID.json ingress: - hostname: api.yourdomain.com service: http://localhost:5000 - service: http_status:404 ``` **Start tunnel:** ```bash sudo systemctl daemon-reload sudo systemctl enable cloudflared-cpa sudo systemctl start cloudflared-cpa sudo systemctl status cloudflared-cpa ``` **Add DNS record in Cloudflare:** ``` Type: CNAME Name: api Target: YOUR_TUNNEL_ID.cfargotunnel.com Proxy: Yes (orange cloud) ``` ## Usage ### API Endpoint Your gateway is now available at: `https://api.yourdomain.com/v1` ### Using with OpenAI SDK **Python:** ```python from openai import OpenAI client = OpenAI( base_url="https://api.yourdomain.com/v1", api_key=os.environ.get("CPA_API_KEY") # The sk- key from deployment ) response = client.chat.completions.create( model="grok-beta", messages=[ {"role": "user", "content": "Hello, Grok!"} ] ) print(response.choices[0].message.content) ``` **JavaScript/TypeScript:** ```javascript import OpenAI from 'openai'; const client = new OpenAI({ baseURL: 'https://api.yourdomain.com/v1', apiKey: process.env.CPA_API_KEY }); const response = await client.chat.completions.create({ model: 'grok-beta', messages: [ { role: 'user', content: 'Hello, Grok!' } ] }); console.log(response.choices[0].message.content); ``` **cURL:** ```bash curl https://api.yourdomain.com/v1/chat/completions \ -H "Content-Type: application/json" \ -H "Authorization: Bearer $CPA_API_KEY" \ -d '{ "model": "grok-beta", "messages": [{"role": "user", "content": "Hello!"}] }' ``` ## Key Commands ### CLIProxyAPI Management ```bash # View logs docker logs -f cpa-gateway # Restart gateway docker restart cpa-gateway # Update to latest docker pull cliproxyapi/cliproxyapi:latest docker restart cpa-gateway # Check credential status curl http://localhost:5000/admin/credentials \ -H "Authorization: Bearer $CPA_API_KEY" # Health check curl http://localhost:5000/health ``` ### Credential Sync Script ```bash # Sync from local to VM SRC=./credentials VM_HOST=user@vm.com bash scripts/sync_credentials.sh # Dry run (show what would be copied) DRY_RUN=1 SRC=./credentials VM_HOST=user@vm.com bash scripts/sync_credentials.sh # Custom auth directory SRC=./credentials VM_HOST=user@vm.com AUTH_DIR=/custom/path bash scripts/sync_credentials.sh ``` ### Email Worker Queries ```bash # Query D1 for received codes wrangler d1 execute email_codes --command="SELECT * FROM verification_codes ORDER BY received_at DESC LIMIT 10" # Clear old codes (older than 1 hour) wrangler d1 execute email_codes --command="DELETE FROM verification_codes WHERE received_at < datetime('now', '-1 hour')" # View worker logs wrangler tail ``` ### Tunnel Management ```bash # Check tunnel status sudo systemctl status cloudflared-cpa # View tunnel logs sudo journalctl -u cloudflared-cpa -f # Restart tunnel sudo systemctl restart cloudflared-cpa # List all tunnels cloudflared tunnel list # Delete tunnel cloudflared tunnel delete cpa-gateway ``` ## Configuration ### CLIProxyAPI Environment Variables ```bash # In deploy_vm.sh or docker-compose.yml CPA_PORT=5000 # Gateway port CPA_AUTH_DIR=/opt/cpa/auth # Credentials directory CPA_LOG_LEVEL=info # debug, info, warn, error CPA_POOL_SIZE=10 # Max concurrent requests per credential CPA_RETRY_ATTEMPTS=3 # Failed request retries CPA_HEALTH_CHECK_INTERVAL=60 # Credential health check (seconds) ``` ### Worker Environment Variables Edit `wrangler.toml`: ```toml [vars] ALLOWED_DOMAINS = "x.ai,openai.com,anthropic.com" MAX_CODE_AGE_MINUTES = 10 AUTO_CLEANUP_ENABLED = "true" ``` ### Rate Limiting Configure per-credential in JSON: ```json { "provider": "grok", "api_key": "...", "rate_limit": { "requests_per_minute": 60, "tokens_per_minute": 100000, "requests_per_day": 5000 } } ``` ## Common Patterns ### Multi-Provider Setup ```bash # auth directory structure /opt/cpa/auth/ ├── grok_account1.json ├── grok_account2.json ├── openai_personal.json ├── openai_work.json └── anthropic_main.json ``` Each credential is automatically pooled. CLIProxyAPI routes based on model name: - `grok-*` → Grok credentials - `gpt-*` → OpenAI credentials - `claude-*` → Anthropic credentials ### Automatic Failover ```python # Client code doesn't change - failover is automatic client = OpenAI( base_url="https://api.yourdomain.com/v1", api_key=os.environ.get("CPA_API_KEY") ) # If grok_account1 fails, CLIProxyAPI automatically tries grok_account2 response = client.chat.completions.create( model="grok-beta", messages=[{"role": "user", "content": "Test"}] ) ``` ### Streaming Responses ```python stream = client.chat.completions.create( model="grok-beta", messages=[{"role": "user", "content": "Write a story"}], stream=True ) for chunk in stream: if chunk.choices[0].delta.content: print(chunk.choices[0].delta.content, end='') ``` ### Monitoring Credential Usage ```bash # Check logs for credential selection docker logs cpa-gateway 2>&1 | grep "Using credential" # Example output: # [INFO] Using credential grok_account1 for model grok-beta # [INFO] Request successful with grok_account1 (245ms) # [WARN] Credential grok_account1 rate limited, trying grok_account2 ``` ## Troubleshooting ### Gateway Returns 502 Bad Gateway **Cause:** CLIProxyAPI container not running or no active credentials. **Fix:** ```bash # Check container docker ps | grep cpa-gateway # View logs docker logs cpa-gateway # Verify credentials exist ls -la /opt/cpa/auth/ # Restart docker restart cpa-gateway ``` ### "No active credentials for provider" Error **Cause:** No valid credential JSON files for requested model's provider. **Fix:** ```bash # Check credential format cat /opt/cpa/auth/grok_account1.json # Must have: # - "provider" field matching model prefix # - "api_key" field # - "status": "active" # Force credential reload docker restart cpa-gateway ``` ### Email Worker Not Receiving Codes **Cause:** Email routing not configured or D1 binding missing. **Fix:** ```bash # Test email routing echo "test" | mail -s "Test" test@yourdomain.com # Check worker logs wrangler tail # Verify D1 binding wrangler d1 info email_codes # Redeploy worker wrangler deploy ``` ### Tunnel Connection Issues **Cause:** Tunnel service not running or incorrect credentials. **Fix:**
عرض على GitHub
ملف SKILL.md هذا كبير جدا، لذلك يعرض SkillsMP القسم الاول فقط هنا. عرض على GitHub