Skip to content

Commit 9cce708

Browse files
committed
Add example of custom sandbox domain proxy
1 parent d66c38a commit 9cce708

File tree

6 files changed

+2640
-0
lines changed

6 files changed

+2640
-0
lines changed
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
# TODO: Get your E2B API key from https://e2b.dev/docs/getting-started/api-key
2+
E2B_API_KEY=""
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
.env
2+
node_modules
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
# Custom Sandbox Domain Proxy
2+
3+
Example of mapping custom subdomains to your E2B sandboxes. Access sandboxes at `my-app.yourdomain.com` instead of default URLs.
4+
5+
## Tech Stack
6+
- [E2B Code Interpreter SDK](https://github.com/e2b-dev/code-interpreter)
7+
- Express.js
8+
9+
## How It Works
10+
1. Create E2B sandbox, start Python HTTP server inside (port 8000)
11+
2. Generate custom subdomain (e.g., `happy-blue-tiger`)
12+
3. Map subdomain → sandbox ID in `sandboxCustomSubdomains` object
13+
4. Express proxy extracts subdomain from requests, looks up sandbox ID, forwards to E2B sandbox
14+
5. Works with any domain (`.localhost` for dev, your domain in production)
15+
16+
## Setup
17+
### 1. Set up API keys
18+
- Copy `.env.template` to `.env`
19+
- Get your [E2B API KEY](https://e2b.dev/docs/getting-started/api-key) and add it to `.env`
20+
21+
### 2. Install packagesInstall the E2B Code Interpreter SDK and other dependencies
22+
23+
```bash
24+
npm i
25+
```
26+
27+
### 3. Run the example
28+
```bash
29+
npm run start
30+
```
31+
32+
This creates a sandbox, assigns it a custom subdomain, starts the proxy on port 3000, and opens your browser.
33+
34+
Press `Ctrl+C` to stop and cleanup.
35+
36+
## Use Cases
37+
- Branded URLs instead of random IDs
38+
- Multi-tenant apps: one subdomain per user (`user-123.yourapp.com`)
39+
- Named environments: dev/staging/prod
40+
41+
## Learn More
42+
[E2B Documentation](https://e2b.dev/docs)
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
import { Sandbox } from '@e2b/code-interpreter'
2+
import express from 'express'
3+
import { createProxyMiddleware } from 'http-proxy-middleware'
4+
import open from 'open'
5+
import { uniqueNamesGenerator, adjectives, colors, animals } from 'unique-names-generator'
6+
import 'dotenv/config'
7+
8+
// Start sandbox
9+
const sandbox = await Sandbox.create({
10+
apiKey: process.env.E2B_API_KEY,
11+
})
12+
console.log(`Sandbox created: ${sandbox.sandboxId}`)
13+
14+
15+
// Start python file serving server inside of the sandbox
16+
const PORT_IN_SANDBOX = 8000
17+
await sandbox.commands.run(
18+
`python3 -m http.server ${PORT_IN_SANDBOX}`,
19+
{ background: true, cwd: '/', user: 'root' }
20+
)
21+
console.log(`Python HTTP server started on port ${PORT_IN_SANDBOX} inside sandbox`)
22+
23+
24+
// Start express proxy to proxy requests to the sandbox
25+
// Map custom subdomains to sandbox IDs - users can customize these subdomains however they want.
26+
const customSubdomain = uniqueNamesGenerator({
27+
dictionaries: [adjectives, colors, animals],
28+
separator: '-',
29+
length: 3,
30+
})
31+
const sandboxCustomSubdomains: Record<string, string> = {
32+
[customSubdomain]: sandbox.sandboxId,
33+
}
34+
35+
const app = express()
36+
const PROXY_PORT = process.env.PORT ? parseInt(process.env.PORT) : 80
37+
38+
// Proxy middleware that maps custom subdomains to sandbox IDs
39+
app.use((req, res, next) => {
40+
const host = req.headers.host || ''
41+
const subdomain = host.split('.')[0]
42+
43+
// Check if this is a subdomain request (has at least one dot)
44+
if (!host.includes('.')) {
45+
return res.status(400).send('Please use subdomain format: <custom-subdomain>.<domain>')
46+
}
47+
48+
// Look up sandbox ID by custom subdomain
49+
const sandboxId = sandboxCustomSubdomains[subdomain]
50+
51+
if (!sandboxId) {
52+
return res.status(404).send(`Sandbox with subdomain "${subdomain}" not found`)
53+
}
54+
55+
// Get the sandbox hostname for proxying
56+
const sandboxHost = sandbox.getHost(PORT_IN_SANDBOX)
57+
58+
// Create proxy middleware dynamically
59+
const proxy = createProxyMiddleware({
60+
target: `https://${sandboxHost}`,
61+
changeOrigin: true,
62+
secure: true,
63+
})
64+
65+
return proxy(req, res, next)
66+
})
67+
68+
app.listen(PROXY_PORT, () => {
69+
console.log(`Proxy server running on http://localhost:${PROXY_PORT}`)
70+
console.log(`Sandbox ${sandbox.sandboxId} accessible via custom subdomain: "${customSubdomain}"`)
71+
console.log(`Access via: http://${customSubdomain}.localhost:${PROXY_PORT}/`)
72+
})
73+
74+
// Open browser pointing to the custom subdomain
75+
await open(`http://${customSubdomain}.localhost:${PROXY_PORT}/`)
76+
77+
// Keep process alive and handle cleanup
78+
process.on('SIGINT', async () => {
79+
console.log('\nShutting down...')
80+
await sandbox.kill()
81+
process.exit(0)
82+
})

0 commit comments

Comments
 (0)