Skip to main content

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):
Serves pre-built client via 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

  1. GPU Validation: Verify NVIDIA GPU and Vulkan ICD
  2. Display Setup: Try Xorg → Xvfb → Ozone headless
  3. WebGPU Test: Preflight check with Chrome
  4. Environment Persistence: Save settings to .env
  5. PM2 Configuration: Export GPU mode to ecosystem.config.cjs
  6. 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
Stream not starting:
  • 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
Browser crashes immediately:
  • GPU sandbox bypass flags missing
  • Check Chrome executable path
  • Verify GPU is accessible: nvidia-smi
Audio not captured:
  • 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 .env or GitHub Secrets
  • Never hardcode credentials in code
  • Use .gitignore to block .env files

Secret Rotation

Access Control

Troubleshooting

Deployment Fails at WebGPU Test

Symptom: Deployment exits with “WebGPU initialization failed” Solutions:
  1. Check GPU is accessible: nvidia-smi
  2. Verify Vulkan ICD: cat /usr/share/vulkan/icd.d/nvidia_icd.json
  3. Check display server: echo $DISPLAY && xdpyinfo -display $DISPLAY
  4. Review GPU diagnostics: cat gpu-diagnostics.log
  5. 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:
  1. This is expected behavior (prevents crashes)
  2. Increase interval: BROWSER_RESTART_INTERVAL_MS=3600000 (1 hour)
  3. Monitor memory usage: pm2 monit

Page Load Timeout (>180s)

Symptom: Browser times out loading game page Solutions:
  1. Enable production client build:
  2. Increase timeout: PAGE_NAVIGATION_TIMEOUT_MS=300000
  3. Check network latency to CDN

Audio Not Captured

Symptom: Stream has video but no audio Solutions:
  1. Check PulseAudio: pactl info
  2. Verify sink: pactl list sinks | grep chrome_audio
  3. Check device: PULSE_AUDIO_DEVICE=chrome_audio.monitor
  4. 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 script
  • ecosystem.config.cjs - PM2 process configuration