SSH & VNC Access
For scenarios requiring direct interaction with a sandbox, VoidRun provides SSH and VNC access. This is essential for:
Interactive debugging - Direct terminal access for troubleshooting
Visual AI agents - Browser automation and GUI testing via VNC
Development workflows - Use your preferred IDE with remote development
Manual testing - Interact with applications running in the sandbox
π SSH Access Secure shell access for terminal-based interaction and scripting.
π₯οΈ VNC Access Graphical desktop access for browser automation and GUI apps.
β‘ PTY Streaming WebSocket-based terminal streaming via SDK for real-time interaction.
SSH Access
SSH is pre-installed and enabled in all VoidRun images. You can connect directly to your sandbox using SSH clients.
Prerequisites
SSH access requires:
A running sandbox
SSH credentials (host, port, username, password/key)
Network connectivity to the sandbox
SSH credentials are typically provided in the sandbox creation response or via a dedicated API endpoint. The exact method depends on your VoidRun configuration.
Retrieving SSH Credentials
import { VoidRun } from '@voidrun/sdk' ;
const vr = new VoidRun ({ apiKey: process . env . VOIDRUN_API_KEY });
// Create a sandbox
const sandbox = await vr . createSandbox ({
name: 'ssh-demo' ,
cpu: 2 ,
mem: 2048
});
// TODO: Verify exact method for retrieving SSH credentials
// SSH credentials may be in the sandbox response or via a dedicated method
// Example expected structure:
// const sshConfig = await sandbox.getSshConfig();
// console.log('SSH Host:', sshConfig.host);
// console.log('SSH Port:', sshConfig.port);
// console.log('SSH User:', sshConfig.username);
// console.log('SSH Password:', sshConfig.password);
// For now, check sandbox metadata for SSH info
console . log ( 'Sandbox ID:' , sandbox . id );
console . log ( 'Sandbox:' , JSON . stringify ( sandbox , null , 2 ));
Connecting via SSH
Once you have the SSH credentials, connect using your SSH client:
CLI Connection
Using SSH Config
SCP File Transfer
# Connect using password
ssh -p < POR T > < USERNAM E > @ < HOS T >
# Example: ssh -p 2222 root@192.168.1.100
# Connect using private key
ssh -p < POR T > -i ~/.ssh/voidrun_key < USERNAM E > @ < HOS T >
# Connect with verbose output for debugging
ssh -v -p < POR T > < USERNAM E > @ < HOS T >
SSH via SDK (PTY Streaming)
For programmatic terminal access, use the PTY streaming API:
import { VoidRun } from '@voidrun/sdk' ;
const vr = new VoidRun ({ apiKey: process . env . VOIDRUN_API_KEY });
const sandbox = await vr . getSandbox ( 'sandbox-id' );
// Connect to PTY for interactive terminal access
const pty = await sandbox . pty . connect ({
sessionId: 'my-session' , // Optional: persistent session
cols: 80 ,
rows: 24
});
// Handle terminal output
pty . onData (( data : string ) => {
process . stdout . write ( data );
});
// Send input to terminal
pty . write ( 'ls -la \n ' );
pty . write ( 'pwd \n ' );
// Resize terminal
await pty . resize ( 120 , 40 );
// Disconnect when done
// pty.close();
VNC Access
VNC provides graphical desktop access to your sandbox. This is essential for:
Browser automation - Run Selenium, Playwright, or Puppeteer with visible browsers
GUI testing - Test desktop applications with real user interaction
Visual AI agents - Enable AI to interact with graphical interfaces
Remote development - Use GUI-based IDEs and tools
VNC is not pre-installed in default VoidRun images. You need to install a desktop environment and VNC server, or use a custom image with VNC pre-configured.
Installing VNC Server
import { VoidRun } from '@voidrun/sdk' ;
const vr = new VoidRun ({ apiKey: process . env . VOIDRUN_API_KEY });
const sandbox = await vr . createSandbox ({
name: 'vnc-sandbox' ,
cpu: 4 ,
mem: 4096 // 4GB for GUI applications
});
// Install desktop environment and VNC server
console . log ( 'Installing desktop environment and VNC...' );
await sandbox . exec ({
command: 'sudo apt-get update && sudo apt-get install -y xfce4 xfce4-goodies tightvncserver'
});
// Set VNC password
await sandbox . exec ({
command: 'mkdir -p ~/.vnc && echo "voidrun" | vncpasswd -f > ~/.vnc/passwd && chmod 600 ~/.vnc/passwd'
});
// Start VNC server
await sandbox . exec ({ command: 'vncserver :1 -geometry 1920x1080 -depth 24' });
// Verify VNC is running
const result = await sandbox . exec ({ command: 'vncserver -list' });
console . log ( 'VNC sessions:' , result . data ?. stdout );
Retrieving VNC Connection Details
import { VoidRun } from '@voidrun/sdk' ;
const vr = new VoidRun ({ apiKey: process . env . VOIDRUN_API_KEY });
const sandbox = await vr . getSandbox ( 'sandbox-id' );
// TODO: Verify exact method for retrieving VNC connection details
// VNC connection details may be retrieved via:
// 1. A dedicated API endpoint
// 2. The sandbox metadata
// 3. Port forwarding configuration
// Example expected structure:
// const vncConfig = await sandbox.getVncConfig();
// console.log('VNC Host:', vncConfig.host);
// console.log('VNC Port:', vncConfig.port); // Usually 5901 for :1 display
// console.log('VNC Password:', vncConfig.password);
// console.log('VNC URL:', vncConfig.url); // For web-based VNC clients
// For now, check VNC server status
const result = await sandbox . exec ({ command: 'vncserver -list' });
console . log ( 'VNC sessions:' , result . data ?. stdout );
Connecting via VNC Client
RealVNC Viewer
TigerVNC
SSH Tunnel (Recommended for Security)
# Connect using VNC client
vncviewer < HOS T > : < POR T >
# Example for display :1 (port 5901)
vncviewer 192.168.1.100:5901
# With specific quality settings
vncviewer -Quality=High -FullScreen < HOS T > : < POR T >
Browser-Based VNC (noVNC)
For web-based VNC access without a client:
import { VoidRun } from '@voidrun/sdk' ;
const vr = new VoidRun ({ apiKey: process . env . VOIDRUN_API_KEY });
const sandbox = await vr . getSandbox ( 'sandbox-id' );
// Install noVNC for browser-based access
await sandbox . exec ({
command: 'sudo apt-get install -y novnc websockify'
});
// Start noVNC web server
await sandbox . exec ({
command: 'websockify --web=/usr/share/novnc/ 6080 localhost:5901 &'
});
// TODO: Verify how to get the noVNC URL
// Expected: https://<host>:6080/vnc.html
console . log ( 'noVNC should be available at the sandbox host on port 6080' );
Browser Automation with VNC
VNC is particularly useful for visual AI agents and browser automation:
import { VoidRun } from '@voidrun/sdk' ;
const vr = new VoidRun ({ apiKey: process . env . VOIDRUN_API_KEY });
const sandbox = await vr . getSandbox ( 'vnc-sandbox' );
// Install browser and automation tools
await sandbox . exec ({
command: 'sudo apt-get install -y chromium-browser chromium-chromedriver'
});
// Install Python Selenium
await sandbox . exec ({ command: 'pip install selenium' });
// Run a browser automation script
const script = `
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
options = Options()
options.add_argument('--no-sandbox')
options.add_argument('--disable-dev-shm-usage')
driver = webdriver.Chrome(options=options)
driver.get('https://example.com')
print('Page title:', driver.title)
driver.save_screenshot('/tmp/screenshot.png')
driver.quit()
` ;
await sandbox . fs . uploadFile ( '/tmp/automation.py' , script );
const result = await sandbox . exec ({ command: 'python /tmp/automation.py' });
console . log ( result . data ?. stdout );
// Download screenshot
const screenshot = await sandbox . fs . downloadFile ( '/tmp/screenshot.png' );
// Save screenshot locally...
Lifecycle Considerations
SSH and VNC connections will be dropped if the sandbox enters auto-sleep mode. Sandboxes automatically sleep after 5 minutes of inactivity. To maintain connections during active sessions, keep the sandbox alive.
Keeping Sandbox Alive
import { VoidRun } from '@voidrun/sdk' ;
const vr = new VoidRun ({ apiKey: process . env . VOIDRUN_API_KEY });
const sandbox = await vr . getSandbox ( 'sandbox-id' );
// Option 1: Resume sandbox if sleeping
await sandbox . resume ();
// Option 2: Keep-alive with periodic activity
setInterval ( async () => {
await sandbox . exec ({ command: 'echo "keepalive" > /dev/null' });
}, 4 * 60 * 1000 ); // Every 4 minutes (before 5-min timeout)
// Option 3: Run a long-running process
await sandbox . exec ({
command: 'while true; do sleep 60; done &' ,
background: true
});
Detecting Sleep State
import { VoidRun } from '@voidrun/sdk' ;
const vr = new VoidRun ({ apiKey: process . env . VOIDRUN_API_KEY });
// Check sandbox status
const sandbox = await vr . getSandbox ( 'sandbox-id' );
if ( sandbox . status === 'sleeping' ) {
console . log ( 'Sandbox is sleeping, resuming...' );
await sandbox . resume ();
console . log ( 'Sandbox resumed, ready for SSH/VNC' );
}
console . log ( 'Current status:' , sandbox . status );
Troubleshooting
Common SSH Issues
Issue Solution Connection refused Verify SSH service is running: systemctl status ssh Authentication failed Check credentials and ensure password auth is enabled Host key mismatch Remove old key from ~/.ssh/known_hosts Connection timeout Check network connectivity and firewall rules
Common VNC Issues
Issue Solution VNC server wonβt start Check if display :1 is already in use: vncserver -list Black screen Ensure desktop environment is installed properly Connection refused Verify VNC server is running and port is accessible Slow performance Reduce color depth or resolution in VNC settings
Debug Commands
# Check SSH service status
voidrun exec < sandbox-i d > --command "systemctl status ssh --no-pager"
# Check VNC server status
voidrun exec < sandbox-i d > --command "vncserver -list"
# Check listening ports
voidrun exec < sandbox-i d > --command "ss -tlnp"
# Check firewall rules
voidrun exec < sandbox-i d > --command "sudo iptables -L -n"
# View SSH logs
voidrun exec < sandbox-i d > --command "sudo journalctl -u ssh -n 50 --no-pager"
Next Steps
Nested Containers Run Docker and Kubernetes inside your sandboxes.
Tailscale VPN Connect to sandboxes securely via Tailscale.