Nested Containers & Kubernetes
VoidRun’s MicroVM architecture provides a massive advantage over traditional containers: true nested virtualization support . Unlike Docker-in-Docker solutions that require privileged mode and security compromises, VoidRun MicroVMs can run containerized workloads natively with full isolation.
🐳 Docker Inside Run Docker containers natively inside your sandbox with full isolation.
☸️ K3s Support Deploy lightweight Kubernetes clusters for orchestration testing.
🔒 Secure Isolation No privileged mode required - MicroVMs provide native isolation.
Why Nested Containers Matter
Use Case Benefit AI Agent Deployments Deploy multi-container AI pipelines with model servers, databases, and APIs CI/CD Testing Test Docker builds and Kubernetes manifests in isolated environments Development Environments Run full development stacks with databases, queues, and services Security Scanning Analyze container images in isolated sandboxes
Running Docker
Docker is pre-installed in VoidRun’s dcdeploy template. You can run Docker commands immediately after creating a sandbox.
Create a Docker-Enabled Sandbox
import { VoidRun } from '@voidrun/sdk' ;
const vr = new VoidRun ({ apiKey: process . env . VOIDRUN_API_KEY });
// Create sandbox with Docker pre-installed
// TODO: Verify exact templateId for Docker-enabled image
const sandbox = await vr . createSandbox ({
name: 'docker-sandbox' ,
templateId: 'dcdeploy' , // Docker-enabled template
cpu: 4 ,
mem: 4096 // 4GB RAM recommended for Docker workloads
});
// Verify Docker is running
const dockerCheck = await sandbox . exec ({ command: 'docker --version' });
console . log ( 'Docker version:' , dockerCheck . data ?. stdout );
// Check Docker daemon status
const daemonStatus = await sandbox . exec ({ command: 'systemctl status docker --no-pager' });
console . log ( 'Docker daemon:' , daemonStatus . data ?. stdout );
Run a Docker Container
import { VoidRun } from '@voidrun/sdk' ;
const vr = new VoidRun ({ apiKey: process . env . VOIDRUN_API_KEY });
const sandbox = await vr . getSandbox ( 'sandbox-id' );
// Pull and run an nginx container
const runResult = await sandbox . exec ({
command: 'docker run -d --name nginx -p 80:80 nginx:latest'
});
console . log ( 'Container started:' , runResult . data ?. stdout );
// List running containers
const listResult = await sandbox . exec ({ command: 'docker ps' });
console . log ( 'Running containers:' , listResult . data ?. stdout );
// Test nginx is responding
const testResult = await sandbox . exec ({ command: 'curl -s http://localhost:80' });
console . log ( 'Nginx response:' , testResult . data ?. stdout ?. substring ( 0 , 100 ));
Multi-Container Application
import { VoidRun } from '@voidrun/sdk' ;
const vr = new VoidRun ({ apiKey: process . env . VOIDRUN_API_KEY });
const sandbox = await vr . getSandbox ( 'sandbox-id' );
// Create a Docker network
await sandbox . exec ({ command: 'docker network create app-network' });
// Run PostgreSQL
await sandbox . exec ({
command: 'docker run -d --name postgres --network app-network -e POSTGRES_PASSWORD=secret postgres:15'
});
// Run Redis
await sandbox . exec ({
command: 'docker run -d --name redis --network app-network redis:7'
});
// Run application container
await sandbox . exec ({
command: 'docker run -d --name app --network app-network -p 3000:3000 myapp:latest'
});
// Verify all containers are running
const result = await sandbox . exec ({ command: 'docker ps --format "table {{.Names}} \t {{.Status}}"' });
console . log ( result . data ?. stdout );
Running K3s (Lightweight Kubernetes)
K3s is a lightweight Kubernetes distribution perfect for testing and development. Run it inside your VoidRun sandbox for ephemeral Kubernetes environments.
K3s requires significant resources. We recommend allocating at least 4 CPU cores and 8GB RAM for K3s workloads.
Install and Start K3s
import { VoidRun } from '@voidrun/sdk' ;
const vr = new VoidRun ({ apiKey: process . env . VOIDRUN_API_KEY });
// Create sandbox with sufficient resources for K3s
const sandbox = await vr . createSandbox ({
name: 'k3s-sandbox' ,
templateId: 'dcdeploy' ,
cpu: 4 ,
mem: 8192 // 8GB RAM for K3s
});
// Install K3s
console . log ( 'Installing K3s (this may take a minute)...' );
const installResult = await sandbox . exec ({
command: 'curl -sfL https://get.k3s.io | sh -' ,
timeout: 120000 // 2 minute timeout
});
console . log ( 'K3s installed:' , installResult . data ?. stdout );
// Wait for K3s to be ready
await sandbox . exec ({
command: 'sleep 10 && systemctl status k3s --no-pager'
});
// Verify K3s is running
const statusResult = await sandbox . exec ({ command: 'kubectl get nodes' });
console . log ( 'K3s nodes:' , statusResult . data ?. stdout );
Deploy to K3s
import { VoidRun } from '@voidrun/sdk' ;
const vr = new VoidRun ({ apiKey: process . env . VOIDRUN_API_KEY });
const sandbox = await vr . getSandbox ( 'sandbox-id' );
// Create a deployment
await sandbox . exec ({
command: 'kubectl create deployment nginx --image=nginx:latest'
});
// Scale the deployment
await sandbox . exec ({ command: 'kubectl scale deployment nginx --replicas=3' });
// Expose the deployment
await sandbox . exec ({
command: 'kubectl expose deployment nginx --port=80 --target-port=80 --type=NodePort'
});
// Check pods are running
const podsResult = await sandbox . exec ({ command: 'kubectl get pods -o wide' });
console . log ( 'Pods:' , podsResult . data ?. stdout );
// Get services
const svcResult = await sandbox . exec ({ command: 'kubectl get svc' });
console . log ( 'Services:' , svcResult . data ?. stdout );
Resource Considerations
Running nested containers and Kubernetes requires careful resource planning. Insufficient CPU or RAM will cause containers to fail or perform poorly.
Recommended Resource Allocation
Workload CPU RAM Notes Single Docker container 2 2GB Light workloads only Multi-container app 4 4GB Database + app + cache K3s cluster 4 8GB Minimum for K3s + workloads K3s + multiple services 8 16GB Production-like testing
Monitoring Resource Usage
import { VoidRun } from '@voidrun/sdk' ;
const vr = new VoidRun ({ apiKey: process . env . VOIDRUN_API_KEY });
const sandbox = await vr . getSandbox ( 'sandbox-id' );
// Check system resources
const memInfo = await sandbox . exec ({ command: 'free -h' });
console . log ( 'Memory:' , memInfo . data ?. stdout );
const cpuInfo = await sandbox . exec ({ command: 'nproc && cat /proc/loadavg' });
console . log ( 'CPU:' , cpuInfo . data ?. stdout );
// Check Docker resource usage
const dockerStats = await sandbox . exec ({ command: 'docker stats --no-stream' });
console . log ( 'Docker stats:' , dockerStats . data ?. stdout );
// Check disk usage
const diskUsage = await sandbox . exec ({ command: 'df -h' });
console . log ( 'Disk:' , diskUsage . data ?. stdout );
Cleanup
Remove containers and free resources when done:
import { VoidRun } from '@voidrun/sdk' ;
const vr = new VoidRun ({ apiKey: process . env . VOIDRUN_API_KEY });
const sandbox = await vr . getSandbox ( 'sandbox-id' );
// Stop and remove all Docker containers
await sandbox . exec ({ command: 'docker stop $(docker ps -aq) 2>/dev/null || true' });
await sandbox . exec ({ command: 'docker rm $(docker ps -aq) 2>/dev/null || true' });
// Remove unused images
await sandbox . exec ({ command: 'docker image prune -af' });
// Remove unused volumes
await sandbox . exec ({ command: 'docker volume prune -f' });
console . log ( 'Cleanup complete' );
Next Steps
SSH & VNC Access Connect directly to your sandbox via SSH or VNC for interactive access.
Custom Images Create custom images with pre-installed Docker or K3s configurations.