Vast.ai GPU Streaming Deployment
This guide covers deploying Hyperscape’s streaming duel arena on Vast.ai GPU servers for live RTMP broadcasting to Twitch, Kick, X/Twitter, and other platforms.Prerequisites
Required
- Vast.ai account with GPU instance
- NVIDIA GPU with Vulkan support (verified via
nvidia-smi) - GitHub repository with secrets configured
- Stream keys for target platforms (Twitch, Kick, X/Twitter)
GPU Requirements
- NVIDIA GPU: Required for WebGPU via ANGLE/Vulkan backend
- Vulkan ICD: Must be available at
/usr/share/vulkan/icd.d/nvidia_icd.json - DRI/DRM Access: Optional but recommended for best performance (Xorg mode)
Deployment Architecture
The deployment script (scripts/deploy-vast.sh) attempts GPU rendering modes in this order:
1. Xorg with NVIDIA (Best Performance)
- Requirements: DRI/DRM device access (
/dev/dri/card*) - Display: Real X server with NVIDIA GLX driver
- WebGPU: Direct GPU access via NVIDIA driver
- Status:
DUEL_CAPTURE_USE_XVFB=false,DISPLAY=:0
2. Xvfb with NVIDIA Vulkan (Fallback)
- Requirements: NVIDIA GPU accessible, no DRI/DRM needed
- Display: Virtual framebuffer (Xvfb) on
:99 - WebGPU: Chrome uses ANGLE/Vulkan to access GPU
- Status:
DUEL_CAPTURE_USE_XVFB=true,DISPLAY=:99
3. Ozone Headless with GPU (Experimental)
- Requirements: NVIDIA GPU with Vulkan
- Display: No X server, Chrome’s
--ozone-platform=headless - WebGPU: Direct Vulkan access via Chrome
- Status:
STREAM_CAPTURE_OZONE_HEADLESS=true,DISPLAY=(empty)
4. Headless Software Rendering (NOT SUPPORTED)
- WebGPU: WILL NOT WORK
- Deployment: FAILS with error message
- Reason: WebGPU requires hardware GPU acceleration
WebGPU Validation
The deployment script performs comprehensive WebGPU validation:1. GPU Hardware Check
2. Vulkan ICD Verification
3. Display Server Check
4. WebGPU Preflight Test
- Launches Chrome with GPU flags
- Navigates to blank page
- Tests
navigator.gpu.requestAdapter()with 30s timeout - Tests
renderer.init()with 60s timeout - Extracts chrome://gpu diagnostics
- Deployment fails if WebGPU cannot initialize
5. GPU Diagnostics Capture
Environment Persistence
Settings are persisted to.env for PM2 restarts:
Stream Capture Configuration
Chrome Flags (GPU Sandbox Bypass)
Required for container GPU access:Capture Modes
- CDP (default): Chrome DevTools Protocol screencast
- WebCodecs: Native VideoEncoder API (experimental)
- MediaRecorder: Legacy fallback
Timeouts & Recovery
- Probe Timeout: 5s on evaluate calls to prevent hanging
- Probe Retry: Proceeds after 5 consecutive timeouts (browser unresponsive)
- Viewport Recovery: Automatic restoration on resolution mismatch
- Browser Restart: Every 45 minutes to prevent WebGPU OOM crashes
Production Client Build
Enable for faster page loads (fixes 180s timeout issues):vite preview instead of JIT dev server.
Audio Capture
PulseAudio Configuration
RTMP Multi-Streaming
Supported Platforms
- Twitch:
TWITCH_STREAM_KEY - Kick:
KICK_STREAM_KEY,KICK_RTMP_URL - X/Twitter:
X_STREAM_KEY,X_RTMP_URL - YouTube: Disabled by default (high latency)
FFmpeg Tee Muxer
Single-encode multi-output for efficiency:Stream Encoding
Health Monitoring
GitHub Secrets Configuration
Set these in your repository’s Settings → Secrets and variables → Actions:Required Secrets
Deployment Workflow
Automated Deployment (GitHub Actions)
Manual Deployment
Deployment Steps
- GPU Validation: Verify NVIDIA GPU and Vulkan ICD
- Display Setup: Try Xorg → Xvfb → Ozone headless
- WebGPU Test: Preflight check with Chrome
- Environment Persistence: Save settings to
.env - PM2 Configuration: Export GPU mode to ecosystem.config.cjs
- Service Start: Launch game server + RTMP bridge via PM2
Monitoring & Diagnostics
Check Deployment Status
WebGPU Diagnostics
Common Issues
WebGPU initialization hangs:- Check GPU diagnostics log
- Verify Vulkan ICD is present
- Ensure display server is running
- Review Chrome flags in ecosystem.config.cjs
- Check RTMP bridge logs:
pm2 logs rtmp-bridge - Verify stream keys are set correctly
- Test with single destination first
- Check FFmpeg is installed:
which ffmpeg
- GPU sandbox bypass flags missing
- Check Chrome executable path
- Verify GPU is accessible:
nvidia-smi
- Check PulseAudio is running:
pactl info - Verify virtual sink exists:
pactl list sinks - Check XDG_RUNTIME_DIR is set
Performance Tuning
Stream Quality
Browser Performance
Resource Limits
Security Best Practices
Never Commit Secrets
- All stream keys must be in
.envor GitHub Secrets - Never hardcode credentials in code
- Use
.gitignoreto block.envfiles
Secret Rotation
Access Control
Troubleshooting
Deployment Fails at WebGPU Test
Symptom: Deployment exits with “WebGPU initialization failed” Solutions:- Check GPU is accessible:
nvidia-smi - Verify Vulkan ICD:
cat /usr/share/vulkan/icd.d/nvidia_icd.json - Check display server:
echo $DISPLAY && xdpyinfo -display $DISPLAY - Review GPU diagnostics:
cat gpu-diagnostics.log - Try different GPU mode: Set
STREAM_CAPTURE_OZONE_HEADLESS=true
Stream Stops After 45 Minutes
Symptom: Browser restarts, stream briefly interrupts Explanation: Automatic browser restart prevents WebGPU OOM crashes Solutions:- This is expected behavior (prevents crashes)
- Increase interval:
BROWSER_RESTART_INTERVAL_MS=3600000(1 hour) - Monitor memory usage:
pm2 monit
Page Load Timeout (>180s)
Symptom: Browser times out loading game page Solutions:- Enable production client build:
- Increase timeout:
PAGE_NAVIGATION_TIMEOUT_MS=300000 - Check network latency to CDN
Audio Not Captured
Symptom: Stream has video but no audio Solutions:- Check PulseAudio:
pactl info - Verify sink:
pactl list sinks | grep chrome_audio - Check device:
PULSE_AUDIO_DEVICE=chrome_audio.monitor - Enable audio:
STREAM_AUDIO_ENABLED=true
Advanced Configuration
Custom Chrome Executable
Low-Latency Streaming
Multiple RTMP Destinations
Monitoring
PM2 Dashboard
Resource Usage
Stream Health
Cost Optimization
GPU Selection
- Minimum: GTX 1060 (6GB VRAM)
- Recommended: RTX 3060 (12GB VRAM)
- Optimal: RTX 4070 (12GB VRAM)
Instance Configuration
- vCPUs: 4-8 cores recommended
- RAM: 16GB minimum, 32GB recommended
- Storage: 50GB minimum for assets + logs
Spot vs On-Demand
- Spot: Cheaper but can be interrupted
- On-Demand: More expensive but guaranteed uptime
- Recommendation: Use on-demand for production streams
See Also
- duel-stack.md - Local duel stack setup
- betting-production-deploy.md - Cloudflare + Railway deployment
scripts/deploy-vast.sh- Deployment automation scriptecosystem.config.cjs- PM2 process configuration