Skip to main content

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 CaseBenefit
AI Agent DeploymentsDeploy multi-container AI pipelines with model servers, databases, and APIs
CI/CD TestingTest Docker builds and Kubernetes manifests in isolated environments
Development EnvironmentsRun full development stacks with databases, queues, and services
Security ScanningAnalyze 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.
WorkloadCPURAMNotes
Single Docker container22GBLight workloads only
Multi-container app44GBDatabase + app + cache
K3s cluster48GBMinimum for K3s + workloads
K3s + multiple services816GBProduction-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.