Deploy E2B AI Code Sandboxes on RamNode
Secure, isolated sandbox execution for AI-generated code powered by Firecracker microVMs. From API key to production in minutes.
What Is E2B?
E2B is an open-source infrastructure platform for running AI-generated code in secure, isolated sandboxes. When an AI agent writes and executes code, that code needs to run somewhere isolated from your host system. E2B solves this with lightweight sandboxes that boot in under 200ms, support full Linux environments, and can run any language or framework. Each sandbox is ephemeral and fully isolated — malicious or buggy code cannot escape the microVM boundary.
Common use cases:
- AI coding assistants that execute code to verify their answers
- Data analysis agents that run Python scripts on user-uploaded files
- LLM applications needing a "code interpreter" feature like ChatGPT
- RL pipelines requiring thousands of parallel execution environments
- SaaS platforms where users submit custom scripts or plugins
E2B is licensed under Apache 2.0 and the SDK is available for Python and JavaScript/TypeScript.
Choosing Your Deployment Path
Path 1 — Managed API (Recommended)
Your application runs on a RamNode VPS and connects to E2B's cloud infrastructure via API key. The sandboxes run on E2B's servers. This is the fastest path to production and works with any RamNode KVM VPS plan.
Path 2 — Self-hosted E2B Infrastructure
You run the entire E2B stack on your own hardware. Requires bare-metal or a dedicated server with KVM virtualization exposed directly to the OS. Covered in the Advanced section at the end.
Recommended Plans (Managed API):
| Plan | Price | Best For |
|---|---|---|
| SSD 2G | $7/mo | Single-service E2B app with moderate request volume |
| SSD 4G | $14/mo | Node.js or Python apps with concurrent sandbox sessions |
| SSD 8G | $28/mo | Full web application alongside E2B integration |
Provision the Server
Deploy a new VPS with Ubuntu 24.04 and connect via SSH.
ssh root@YOUR_SERVER_IP
apt update && apt upgrade -yCreate a non-root user for running your application:
adduser deploy
usermod -aG sudo deployInstall Node.js
Install a current LTS release via NodeSource:
curl -fsSL https://deb.nodesource.com/setup_22.x | sudo -E bash -
apt install -y nodejs
node -v # should show v22.x
npm -vInstall Python (Optional)
Ubuntu 24.04 includes Python 3.12. Verify and install pip:
python3 --version
apt install -y python3-pip python3-venvGet Your E2B API Key
Sign up at e2b.dev and retrieve your API key from the dashboard. You will set this as an environment variable — never hardcode it in your application.
Create Your Project
Switch to your deploy user and set up a working directory:
su - deploy
mkdir ~/e2b-app && cd ~/e2b-app
npm init -y
npm install @e2b/code-interpreterOr for a Python project:
python3 -m venv venv
source venv/bin/activate
pip install e2b-code-interpreterSet Environment Variables
cat > ~/.env << 'EOF'
E2B_API_KEY=your_api_key_here
EOF
chmod 600 ~/.envWrite Your First E2B Integration
Node.js example — code execution:
// app.js
import { Sandbox } from '@e2b/code-interpreter';
async function runUserCode(code) {
const sandbox = await Sandbox.create();
try {
const execution = await sandbox.runCode(code);
if (execution.error) {
console.error('Execution error:', execution.error);
return { success: false, error: execution.error.value };
}
return {
success: true,
output: execution.text,
logs: execution.logs,
};
} finally {
await sandbox.kill();
}
}
const result = await runUserCode(`
import numpy as np
data = np.array([1, 2, 3, 4, 5])
print(f"Mean: {data.mean()}, Std: {data.std():.2f}")
`);
console.log(result);Python example:
# app.py
from e2b_code_interpreter import Sandbox
import os
def run_in_sandbox(code: str) -> dict:
with Sandbox() as sandbox:
execution = sandbox.run_code(code)
if execution.error:
return {"success": False, "error": execution.error.value}
return {
"success": True,
"output": execution.text,
"results": [str(r) for r in execution.results],
}
if __name__ == "__main__":
result = run_in_sandbox("""
import pandas as pd
df = pd.DataFrame({
'name': ['Alice', 'Bob', 'Carol'],
'score': [92, 78, 88]
})
print(df.describe())
""")
print(result)Test the Integration
export E2B_API_KEY=your_key_here
node app.jssource venv/bin/activate
export E2B_API_KEY=your_key_here
python app.pyYou should see output from the sandboxed code. The sandbox boots, runs the code, returns the result, and shuts down — all within a few hundred milliseconds.
Build an HTTP API Around Your Sandbox
Express (Node.js) example:
npm install express// server.js
import express from 'express';
import { Sandbox } from '@e2b/code-interpreter';
const app = express();
app.use(express.json());
app.post('/execute', async (req, res) => {
const { code, language = 'python' } = req.body;
if (!code) {
return res.status(400).json({ error: 'code is required' });
}
let sandbox;
try {
sandbox = await Sandbox.create({ timeoutMs: 30000 });
const execution = await sandbox.runCode(code);
if (execution.error) {
return res.status(422).json({
success: false,
error: execution.error.value,
traceback: execution.error.traceback,
});
}
return res.json({
success: true,
output: execution.text,
logs: {
stdout: execution.logs.stdout,
stderr: execution.logs.stderr,
},
});
} catch (err) {
return res.status(500).json({ error: err.message });
} finally {
if (sandbox) await sandbox.kill();
}
});
app.listen(3000, () => console.log('E2B execution API running on port 3000'));FastAPI (Python) example:
pip install fastapi uvicorn# server.py
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
from e2b_code_interpreter import Sandbox
app = FastAPI()
class CodeRequest(BaseModel):
code: str
timeout: int = 30
@app.post("/execute")
async def execute_code(request: CodeRequest):
try:
with Sandbox(timeout=request.timeout) as sandbox:
execution = sandbox.run_code(request.code)
if execution.error:
raise HTTPException(
status_code=422,
detail={
"error": execution.error.value,
"traceback": execution.error.traceback,
}
)
return {
"success": True,
"output": execution.text,
"stdout": execution.logs.stdout,
"stderr": execution.logs.stderr,
}
except HTTPException:
raise
except Exception as e:
raise HTTPException(status_code=500, detail=str(e))Keep the Service Running with PM2
sudo npm install -g pm2Start your Node.js server:
pm2 start server.js --name e2b-api \
--env E2B_API_KEY=your_key_here
pm2 save
pm2 startupOr Python/uvicorn:
pm2 start "uvicorn server:app --host 0.0.0.0 --port 3000" \
--name e2b-api \
--interpreter none
pm2 save
pm2 startupRun the command PM2 outputs from pm2 startup to enable auto-restart on reboot.
Put Nginx in Front
sudo apt install -y nginxserver {
listen 80;
server_name your-domain.com;
location / {
proxy_pass http://127.0.0.1:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_cache_bypass $http_upgrade;
proxy_read_timeout 60s;
}
}sudo ln -s /etc/nginx/sites-available/e2b-api /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginxAdd SSL with Certbot
sudo apt install -y certbot python3-certbot-nginx
sudo certbot --nginx -d your-domain.comCertbot will auto-configure HTTPS and set up certificate renewal.
Custom Sandbox Templates
Pre-install packages so sandboxes don't need to install dependencies on every run.
npm install -g @e2b/cli
e2b loginFROM e2bdev/code-interpreter:latest
# Pre-install common data science packages
RUN pip install numpy pandas matplotlib seaborn scikit-learn requests
# Pre-install Node.js packages if needed
RUN npm install -g typescript
# Add any system dependencies
RUN apt-get update && apt-get install -y \
ffmpeg \
&& rm -rf /var/lib/apt/lists/*e2b template build --name my-data-sandboxUse the returned template ID when creating sandboxes:
const sandbox = await Sandbox.create({ template: 'your-template-id' });Working with Files and Persistent State
Upload files to the sandbox and retrieve output:
import fs from 'fs';
const sandbox = await Sandbox.create();
// Upload a CSV for analysis
const fileContent = fs.readFileSync('./data.csv');
await sandbox.files.write('/home/user/data.csv', fileContent);
const execution = await sandbox.runCode(`
import pandas as pd
df = pd.read_csv('/home/user/data.csv')
print(df.describe().to_string())
`);
// Download the result
const output = await sandbox.files.read('/home/user/output.png');
fs.writeFileSync('./output.png', output);
await sandbox.kill();For sessions that persist between requests, keep the sandbox alive:
// Create once, reuse across requests
const sandbox = await Sandbox.create({ timeoutMs: 3600000 }); // 1-hour timeout
const sandboxId = sandbox.sandboxId;
// Later, reconnect to the same sandbox
const existingSandbox = await Sandbox.connect(sandboxId);
const execution = await existingSandbox.runCode('print(x)'); // variables persistMonitoring & Observability
pm2 logs e2b-api # live log tail
pm2 logs e2b-api --lines 200 # last 200 linesAdd structured logging to track sandbox usage:
async function runWithLogging(code, requestId) {
const startTime = Date.now();
let sandbox;
try {
sandbox = await Sandbox.create();
console.log(JSON.stringify({
event: 'sandbox_created',
sandboxId: sandbox.sandboxId,
requestId,
}));
const execution = await sandbox.runCode(code);
const durationMs = Date.now() - startTime;
console.log(JSON.stringify({
event: 'sandbox_completed',
sandboxId: sandbox.sandboxId,
requestId,
durationMs,
success: !execution.error,
}));
return execution;
} finally {
if (sandbox) await sandbox.kill();
}
}Security Hardening
Firewall Configuration
sudo apt install -y ufw
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow ssh
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw enableRate Limiting in Nginx
# Add to /etc/nginx/nginx.conf http block
limit_req_zone $binary_remote_addr zone=execute_limit:10m rate=10r/m;
# Add to your server block's location /execute
location /execute {
limit_req zone=execute_limit burst=5 nodelay;
proxy_pass http://127.0.0.1:3000;
...
}Input Validation
app.post('/execute', async (req, res) => {
const { code } = req.body;
if (!code || typeof code !== 'string') {
return res.status(400).json({ error: 'Invalid code input' });
}
if (code.length > 50000) {
return res.status(400).json({ error: 'Code exceeds maximum length' });
}
// proceed with sandbox execution
});Advanced — Self-Hosting E2B Infrastructure
Note: Self-hosting is significantly more complex than the managed API. It requires hardware-level KVM access — bare-metal or a dedicated server with virtualization extensions exposed to the guest OS.
Hardware Requirements
| Component | Requirement |
|---|---|
| CPU | Intel VT-x or AMD-V extensions |
| RAM | 16 GB min; 32 GB+ recommended |
| Disk | SSD; fast I/O for image loading |
| OS | Linux with KVM enabled |
ls -la /dev/kvm
# Should output: crw-rw---- 1 root kvm ...Infrastructure Stack
- • API server — sandbox lifecycle requests and authentication
- • Orchestrator + Template Manager — Firecracker VM pools
- • Client Proxy — routes traffic to correct sandboxes
- • Postgres — team, user, and API key data
- • Redis — session state and caching
- • ClickHouse — usage metrics and analytics
- • Grafana + OpenTelemetry — observability
The E2B infrastructure repo is at github.com/e2b-dev/infra. Their official Terraform tooling targets GCP. Self-hosting on a standalone Linux server requires manual deployment. For current guidance, see the E2B community Discord.
Troubleshooting
Sandbox creation times out
Check that E2B_API_KEY is set correctly. Verify outbound HTTPS: curl https://api.e2b.dev/health
"Module not found" errors inside sandbox
Packages must be installed per-sandbox or pre-installed via a custom template. Use sandbox.runCode('!pip install package-name') for ad-hoc installs.
High API costs on E2B dashboard
Confirm sandboxes are being killed after each request with await sandbox.kill(). Check for unclosed sessions in error paths — use try/finally blocks.
PM2 process exits immediately
Check logs: pm2 logs e2b-api. Confirm the API key environment variable is available to the PM2 process.
Nginx returns 504 Gateway Timeout
Increase proxy_read_timeout in your nginx config. Sandbox execution can take up to 30 seconds for complex code.
