VPS Deployment
Run the RelayPlane proxy on your own VPS or dedicated server for full control over data residency, latency, and cost.
Who is this for? This guide is for teams that need to self-host the proxy — for compliance reasons, to reduce egress costs, or to co-locate it with their own infrastructure. If you just want to get started quickly, see the Quick Start guide instead.
Prerequisites
- •VPS running Ubuntu 22.04+ or Debian 12+ — any provider works (Hetzner, DigitalOcean, Linode, etc.)
- •Node.js 20+ — the proxy requires Node 20 LTS or newer
- •A domain name — needed for TLS. Point an A record at your server IP before running Certbot.
- •At least one AI provider API key — e.g.
ANTHROPIC_API_KEYorOPENAI_API_KEY
1. Install Node.js
Use the NodeSource setup script to install Node 20 LTS on Debian/Ubuntu:
1# Install curl if needed2sudo apt-get update && sudo apt-get install -y curl34# Add NodeSource repo for Node 205curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash -67# Install Node.js8sudo apt-get install -y nodejs910# Verify11node --version # v20.x.x12npm --version2. Install the RelayPlane Proxy
Install the proxy globally so it can be managed as a system service:
1sudo npm install -g @relayplane/proxy23# Verify the binary is available4relayplane --version3. Configure Environment Variables
Create a dedicated directory for the proxy and write an environment file:
1sudo mkdir -p /etc/relayplane2sudo nano /etc/relayplane/.env1# AI Provider Keys (add the ones you use)2ANTHROPIC_API_KEY=sk-ant-...3OPENAI_API_KEY=sk-...4GOOGLE_AI_API_KEY=...5XAI_API_KEY=...67# Proxy port (nginx will forward to this)8RELAYPLANE_PORT=4000910# Optional: your RelayPlane cloud API key for telemetry11RELAYPLANE_API_KEY=rp-...1213NODE_ENV=production14LOG_LEVEL=infoLock down the env file. It contains your API keys — restrict read access to root only:
sudo chmod 600 /etc/relayplane/.env4. Run as a systemd Service
Create a systemd unit file so the proxy starts automatically on boot and restarts on failure:
1[Unit]2Description=RelayPlane Proxy3After=network.target45[Service]6Type=simple7User=nobody8EnvironmentFile=/etc/relayplane/.env9ExecStart=/usr/bin/relayplane start --port $RELAYPLANE_PORT10Restart=on-failure11RestartSec=512StandardOutput=journal13StandardError=journal14SyslogIdentifier=relayplane1516# Security hardening17NoNewPrivileges=true18PrivateTmp=true19ProtectSystem=strict20ProtectHome=true2122[Install]23WantedBy=multi-user.target1# Reload systemd and enable the service2sudo systemctl daemon-reload3sudo systemctl enable relayplane4sudo systemctl start relayplane56# Check it's running7sudo systemctl status relayplane89# Follow live logs10sudo journalctl -u relayplane -fPrefer PM2? Skip systemd and use pm2 start relayplane -- start --port 4000 with pm2 startup to persist across reboots.
4b. Alternatively — Run with PM2
PM2 is a popular process manager for Node.js that simplifies log rotation, clustering, and zero-downtime reloads:
1# Install PM2 globally2sudo npm install -g pm234# Start the proxy, loading env from file5pm2 start relayplane --name relayplane -- start --port 4000 --env-file /etc/relayplane/.env67# Save the process list and generate startup script8pm2 save9pm2 startup # Follow the printed command to enable on boot1011# Useful PM2 commands12pm2 status13pm2 logs relayplane14pm2 restart relayplane15pm2 reload relayplane # zero-downtime reload5. nginx Reverse Proxy
nginx terminates TLS and forwards traffic to the proxy on port 4000:
1sudo apt-get install -y nginx1server {2 listen 80;3 server_name proxy.yourdomain.com;45 # Redirect all HTTP to HTTPS6 return 301 https://$host$request_uri;7}89server {10 listen 443 ssl http2;11 server_name proxy.yourdomain.com;1213 ssl_certificate /etc/letsencrypt/live/proxy.yourdomain.com/fullchain.pem;14 ssl_certificate_key /etc/letsencrypt/live/proxy.yourdomain.com/privkey.pem;15 ssl_protocols TLSv1.2 TLSv1.3;16 ssl_ciphers HIGH:!aNULL:!MD5;1718 # Increase timeouts for long LLM responses19 proxy_read_timeout 120s;20 proxy_send_timeout 120s;2122 location / {23 proxy_pass http://127.0.0.1:4000;24 proxy_http_version 1.1;25 proxy_set_header Host $host;26 proxy_set_header X-Real-IP $remote_addr;27 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;28 proxy_set_header X-Forwarded-Proto $scheme;2930 # Required for streaming responses (SSE / chunked)31 proxy_buffering off;32 proxy_cache off;33 }34}1# Enable the site and reload nginx2sudo ln -s /etc/nginx/sites-available/relayplane /etc/nginx/sites-enabled/relayplane3sudo nginx -t # test config4sudo systemctl reload nginx6. TLS with Let's Encrypt
Certbot issues and auto-renews a free TLS certificate from Let's Encrypt:
1# Install Certbot2sudo apt-get install -y certbot python3-certbot-nginx34# Obtain a certificate (nginx plugin handles nginx config automatically)5sudo certbot --nginx -d proxy.yourdomain.com67# Certbot adds a cron/systemd timer — verify auto-renewal works8sudo certbot renew --dry-runDNS must resolve first. Make sure proxy.yourdomain.com points to your server IP before running Certbot, or the ACME challenge will fail.
7. Firewall Rules
Expose only ports 80 and 443 externally. The proxy port (4000) should only be reachable from localhost:
1# Allow SSH, HTTP, HTTPS2sudo ufw allow OpenSSH3sudo ufw allow 'Nginx Full'45# Block direct access to proxy port from outside6sudo ufw deny 400078# Enable firewall9sudo ufw enable10sudo ufw status8. Point Your AI Tools at the Proxy
Once the proxy is running and nginx is serving HTTPS, update your tools to route through it:
1{2 "env": {3 "ANTHROPIC_BASE_URL": "https://proxy.yourdomain.com/anthropic"4 }5}1OPENAI_BASE_URL=https://proxy.yourdomain.com/openai2OPENAI_API_KEY=your-real-key # still required by the SDK1{2 "mcpServers": {3 "relayplane": {4 "command": "relayplane",5 "args": ["mcp"],6 "env": {7 "RELAYPLANE_BASE_URL": "https://proxy.yourdomain.com"8 }9 }10 }11}9. Health Check & Smoke Test
1# Proxy health endpoint2curl https://proxy.yourdomain.com/health34# Expected response5# {"status":"ok","version":"1.x.x"}67# Quick smoke test — route a real request through the proxy8curl https://proxy.yourdomain.com/anthropic/v1/messages \9 -H "x-api-key: $ANTHROPIC_API_KEY" \10 -H "anthropic-version: 2023-06-01" \11 -H "content-type: application/json" \12 -d '{13 "model": "claude-3-haiku-20240307",14 "max_tokens": 32,15 "messages": [{"role":"user","content":"ping"}]16 }'Updating the Proxy
The proxy ships as an npm package. To update:
1# Install latest version2sudo npm install -g @relayplane/proxy@latest34# Restart the service (systemd)5sudo systemctl restart relayplane67# Or with PM28pm2 restart relayplanePin your version in production. Use @relayplane/proxy@1.8.33 (exact version) rather than @latest so updates are intentional, not automatic.
Troubleshooting
- •502 Bad Gateway from nginx
The proxy isn't running or crashed. Check
sudo systemctl status relayplaneorpm2 logs relayplane. - •Streaming responses time out
Ensure
proxy_read_timeoutandproxy_buffering offare set in your nginx config. LLM streams can run for 30–60s. - •Certbot fails with "Connection refused"
Port 80 must be open. Check
sudo ufw statusand ensure nginx is listening on 80 before running Certbot. - •401 Unauthorized from provider
The API key in
/etc/relayplane/.envis missing or invalid. Confirm withsudo systemctl show relayplane --property=Environment.
Next Steps
- •Proxy Configuration - All available config options and env vars
- •Telemetry - Connect to RelayPlane cloud for cost dashboards
- •Deployment Guide - Docker and serverless deployment options
- •Environment Variables - Complete reference for all supported env vars