Secure, isolated code execution using Docker containers with a universal runtime supporting Python, Node.js, Java, and C++. File watching enables automatic code refresh and hot reload.
- Single Docker image for all languages
- Alpine Linux base (lightweight)
- Pre-installed runtimes
- Fast startup (<1s)
- Container isolation
- Non-root user execution
- Resource limits (CPU, memory, time)
- Network isolation
- Read-only filesystem
- Monitors file changes
- Auto-detects modifications
- Refreshes code in container
- Preserves running state
- 300ms debounce
- Python 3.11: Full standard library
- Node.js 18: NPM packages included
- Java 17: JDK with javac
- C++ (GCC 12): g++ compiler
# Click "Run" button or Ctrl+Enter
# Automatically detects language and executes
Python → python3 main.py
JavaScript → node app.js
Java → javac Main.java && java Main
C++ → g++ main.cpp -o main && ./main# Python
python3 script.py
# Node.js with packages
npm install express
node server.js
# Java
javac HelloWorld.java
java HelloWorld
# C++ with flags
g++ -std=c++17 -o program main.cpp
./programFROM alpine:3.18
# Install runtimes
RUN apk add --no-cache \
python3 py3-pip \
nodejs npm \
openjdk17 \
g++ make
# Create non-root user
RUN adduser -D -u 1000 coderunner
# Set working directory
WORKDIR /workspace
USER coderunner// Resource limits
{
memory: '512m', // 512MB RAM
cpus: '1.0', // 1 CPU core
pidsLimit: 100, // Max 100 processes
networkMode: 'none', // No internet
readonlyRootfs: false // Allow file creation
}
// Security options
{
securityOpt: ['no-new-privileges'],
user: '1000:1000', // Non-root
privileged: false
}┌─────────────────┐
│ File Changed │
│ (Editor Save) │
└────────┬────────┘
│
↓
┌─────────────────┐
│ File Watcher │
│ (300ms delay) │
└────────┬────────┘
│
↓
┌─────────────────┐
│ Copy to │
│ Container │
└────────┬────────┘
│
↓
┌─────────────────┐
│ Execute Code │
│ (Auto-detect) │
└────────┬────────┘
│
↓
┌─────────────────┐
│ Stream Output │
│ (WebSocket) │
└─────────────────┘
// Create container
const container = await docker.createContainer({
Image: 'ai-ide-universal-runner',
WorkingDir: '/workspace',
User: 'coderunner',
HostConfig: {
Memory: 536870912, // 512MB
NanoCpus: 1000000000, // 1 CPU
NetworkMode: 'none'
}
});
// Start container
await container.start();
// Execute command
const exec = await container.exec({
Cmd: ['python3', 'script.py'],
AttachStdout: true,
AttachStderr: true
});
// Stream output
const stream = await exec.start();
stream.pipe(terminalOutput);
// Cleanup
await container.stop();
await container.remove();// Monitor file changes
const watcher = chokidar.watch('/workspace', {
ignored: /(^|[\/\\])\../, // Ignore hidden files
persistent: true,
ignoreInitial: true,
awaitWriteFinish: {
stabilityThreshold: 300,
pollInterval: 100
}
});
// On change
watcher.on('change', async (path) => {
console.log(`File changed: ${path}`);
await syncToContainer(path);
await reloadCode();
});const detectLanguage = (filename) => {
const ext = path.extname(filename);
const languages = {
'.py': {
runtime: 'python3',
command: (file) => `python3 ${file}`
},
'.js': {
runtime: 'node',
command: (file) => `node ${file}`
},
'.java': {
runtime: 'java',
command: (file) => {
const className = path.basename(file, '.java');
return `javac ${file} && java ${className}`;
}
},
'.cpp': {
runtime: 'g++',
command: (file) => {
const output = file.replace('.cpp', '');
return `g++ ${file} -o ${output} && ./${output}`;
}
}
};
return languages[ext];
};# Windows
cd runner-images\universal
docker build -t ai-ide-universal-runner .
# Linux/Mac
cd runner-images/universal
docker build -t ai-ide-universal-runner .
# Or use script
scripts\build-runners.bat # Windows
./scripts/build-runners.sh # Linux/Mac// backend/src/services/execution.service.js
const containerConfig = {
memory: '1g', // Increase to 1GB
cpus: '2.0', // Use 2 CPU cores
pidsLimit: 200 // Allow 200 processes
};// WARNING: Security risk!
HostConfig: {
NetworkMode: 'bridge' // Allow internet
}# Install in container
pip install requests pandas numpy
# Or create requirements.txt
# File: requirements.txt
requests==2.31.0
pandas==2.0.0
# Install
pip install -r requirements.txt// Create package.json
npm init -y
// Install packages
npm install express axios lodash
// Use in code
const express = require('express');
const app = express();// Maven or Gradle not included by default
// Manual JAR management required
javac -cp "lib/*:." Main.java
java -cp "lib/*:." Main| Language | Startup Time | Execution Time (Hello World) |
|---|---|---|
| Python | ~150ms | ~50ms |
| Node.js | ~100ms | ~30ms |
| Java | ~300ms | ~100ms (compile) + 50ms (run) |
| C++ | ~200ms | ~150ms (compile) + 10ms (run) |
- Containers persist between executions
- 5-minute idle timeout
- Faster subsequent runs
- Shared filesystem
1. Docker container isolation
2. Non-root user (UID 1000)
3. No network access
4. Resource limits
5. Read-only system files
6. Process limits
✅ Network attacks (no internet) ✅ Fork bombs (PID limit) ✅ Memory bombs (memory limit) ✅ CPU hogging (CPU limit) ✅ Privilege escalation (non-root) ✅ File system attacks (user permissions)
Solution:
# Check Docker is running
docker ps
# Check image exists
docker images | grep ai-ide-universal-runner
# Build image if missing
cd runner-images/universal
docker build -t ai-ide-universal-runner .Solution:
- Check file syntax errors
- Verify language runtime installed in container
- Check container logs:
docker logs <container_id> - Ensure file permissions are correct
Solution:
// Increase timeout
const EXECUTION_TIMEOUT = 30000; // 30 seconds (default: 10s)