Skip to content

Commit 8e44730

Browse files
committed
updating docs
1 parent b1c2014 commit 8e44730

File tree

6 files changed

+383
-33
lines changed

6 files changed

+383
-33
lines changed

sandboxes/getting_started.md

Lines changed: 25 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,10 @@
1-
## title: "Getting started" description: "Step-by-step walkthrough for enabling Sandboxes, creating your first microVM, running commands, exposing services, and managing secrets."
1+
---
2+
title: "Getting started"
3+
description: "Step-by-step walkthrough for enabling Sandboxes, creating your first microVM, running commands, exposing services, and managing secrets."
4+
---
5+
6+
To use Sandboxes, you need a Deno Deploy account. If you do not have one yet you
7+
can sign up for a free account at [app.deno.com](https://app.deno.com).
28

39
## 1. Access the Sandboxes dashboard
410

@@ -21,7 +27,7 @@ and store it securely. Then export it in your local shell or CI job:
2127
export DENO_DEPLOY_TOKEN=<your-token>
2228
```
2329

24-
::: Tip Token security
30+
:::tip Token security
2531

2632
Treat this token like any other production secret. Rotate it from the dashboard
2733
if it is ever exposed.
@@ -33,15 +39,18 @@ if it is ever exposed.
3339
The SDK works in both Deno and Node.js environments.
3440

3541
```bash
36-
# Deno
42+
# Using Deno
3743
deno add jsr:@deno/sandbox
3844

39-
# npm
45+
# Using npm
4046
npm install @deno/sandbox
41-
```
4247

43-
For Node.js 22 or earlier, replace `await using` with a `try`/`finally` block
44-
when the docs use explicit resource management.
48+
# Using pnpm
49+
pnpm install jsr:@deno/sandbox
50+
51+
# Using yarn
52+
yarn add jsr:@deno/sandbox
53+
```
4554

4655
## 4. Create your first sandbox
4756

@@ -61,13 +70,18 @@ from that VM.
6170

6271
## 5. Run commands and scripts
6372

64-
Sandboxes expose familiar filesystem and process APIs.
73+
Sandboxes expose familiar filesystem and process APIs to run commands, upload files,
74+
and spawn long-running services.
6575

66-
```tsx
67-
// List files, just like a normal server
76+
You can for example list files in the root directory:
77+
78+
```ts
6879
await sandbox.sh`ls -lh /`;
80+
```
6981

70-
// Upload source and run it
82+
Or upload a script and run it:
83+
84+
```ts
7185
await sandbox.writeTextFile("hello.ts", "console.log('Hello from a sandbox')");
7286
const proc = await sandbox.spawn("deno", {
7387
args: ["run", "hello.ts"],
@@ -82,24 +96,6 @@ await proc.status;
8296
You can keep state between commands, stream stdout and stderr, or open an
8397
interactive REPL with `sandbox.repl()` for agent-style workflows.
8498

85-
## 6. Expose HTTP services (optional)
86-
87-
Run dev servers, preview apps, or framework CLIs on any port and publish them
88-
instantly:
89-
90-
```tsx
91-
await sandbox.writeTextFile(
92-
"server.js",
93-
"Deno.serve(() => new Response('Hello from Sandboxes'));",
94-
);
95-
const runtime = await sandbox.createJsRuntime({ entrypoint: "server.js" });
96-
const publicUrl = await sandbox.exposeHttp({ port: 8080 });
97-
console.log(publicUrl); // https://<random>.sandbox.deno.net
98-
```
99-
100-
The URL stays live for the sandbox lifetime, making it perfect for short-lived
101-
QA links or agent generated previews.
102-
10399
## 7. Keep secrets and policies tight
104100

105101
Secrets never appear inside `/proc` or the sandbox environment variables.

sandboxes/index.md

Lines changed: 54 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,6 @@ title: "About Sandboxes"
33
description: "Overview of the Sandboxes microVM platform on Deploy, including capabilities, security model, and ideal use cases."
44
---
55

6-
<a href="https://app.deno.com/" class="docs-cta deploy-cta">Launch the Sandboxes
7-
dashboard</a>
8-
96
Sandboxes bring real Linux microVMs directly to the Deploy global edge. Each
107
sandbox boots in under a second, is API driven from the `@deno/sandbox` SDK, and
118
is torn down as soon as you are done. The result is on-demand compute that feels
@@ -49,7 +46,7 @@ Every sandbox launches with a strict outbound allow list. `allowNet` constrains
4946
the VM at the hypervisor boundary, so even if user code attempts to exfiltrate
5047
data it can only talk to the hosts you approve.
5148

52-
## Run real workloads inside
49+
## Run real workloads
5350

5451
Once the sandbox exists, you get a full Linux environment with files, processes,
5552
package managers, and background services:
@@ -93,6 +90,59 @@ Together, Deno Deploy and Sandboxes form a single workflow: code is created,
9390
proved safe in a sandbox, and deployed globally without new infrastructure or
9491
orchestration layers.
9592

93+
## Runtime support
94+
95+
The Sandboxes SDK is tested and supported on:
96+
97+
- **Deno:** Latest stable version
98+
- **Node.js:** Version 24+
99+
100+
You can use Sandboxes from any environment that can import the `@deno/sandbox`
101+
package and make outbound HTTPS requests to the Deploy API, meaning you can use
102+
Sandboxes in your Node projects, Deno Deploy apps, or even browser-based tools.
103+
104+
:::note await using support
105+
106+
The `await using` syntax requires Node.js 24+. If your project uses earlier
107+
Node.js versions, use try/finally blocks instead:
108+
109+
```ts
110+
import { Sandbox } from "@deno/sandbox";
111+
112+
const sandbox = await Sandbox.create();
113+
try {
114+
// ... use sandbox ...
115+
} finally {
116+
await sandbox.close();
117+
}
118+
```
119+
120+
:::
121+
122+
## Limits
123+
124+
Sandboxes have the following limits:
125+
126+
- **Memory:** 768 MB to 4096 MB, configurable per sandbox
127+
- **CPU:** 2 vCPU, subject to noisy neighbor effects
128+
- **Network:** Outbound only, restricted to `allowNet` hosts
129+
- **Lifetime:** Configurable per sandbox, up to 15 minutes by default
130+
- **Disk**: 10 GB of ephemeral storage
131+
132+
Exceeding these limits may result in throttling or termination of your sandbox.
133+
134+
## Regions
135+
136+
You can specify the region where the sandbox will be created when creating a new sandbox:
137+
138+
```tsx
139+
import { Sandbox } from "@deno/sandbox";
140+
141+
await using sandbox = await Sandbox.create({ region: "ams" });
142+
```
143+
144+
If not specified, the sandbox will be created in the default region.
145+
96146
## Learn more
97147

98148
Ready to try it? Follow the [`Getting started` guide](./getting_started.md) to

sandboxes/reference/TODO.md

Whitespace-only changes.

sandboxes/reference/create.md

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
---
2+
title: "Create a Sandbox"
3+
description: "Learn how to provision a sandbox with the static Sandbox.create() method and configure runtime, network, and lifecycle options."
4+
---
5+
6+
The `Sandbox.create()` static method is the primary entry point for provisioning
7+
an isolated Linux microVM on the Deploy edge. It returns a connected `Sandbox`
8+
instance that you can use to run commands, upload files, expose HTTP endpoints,
9+
or request SSH access.
10+
11+
```tsx
12+
import { Sandbox } from "@deno/sandbox";
13+
14+
await using sandbox = await Sandbox.create();
15+
```
16+
17+
By default, this creates an ephemeral sandbox in the closest Deploy region with
18+
768 MB of RAM, no outbound network access, and a lifetime bound to the current
19+
process. You can tailor the sandbox by passing an options object.
20+
21+
## Available options
22+
23+
| Option | Type | Description |
24+
| ---------- | ------------------------ | ----------------------------------------------------------------------------------------------------------------------- |
25+
| `allowNet` | `string[]` | Outbound allow list enforced at the hypervisor level. Hosts not listed are unreachable, blocking data exfiltration. |
26+
| `region` | `"sjc" | "ams" |
27+
| `memoryMb` | `number` | Allocate between 768 and 4096 MB of RAM for memory-heavy tasks or tighter budgets. |
28+
| `lifetime` | `"session" | "5m" |
29+
| `id` | `string` | Reconnect to an existing sandbox instead of creating a new one (used with `Sandbox.connect`). |
30+
| `metadata` | `Record<string, string>` | Attach arbitrary key/value tags to help identify sandboxes in logs or telemetry. |
31+
| `env` | `Record<string, string>` | Set initial environment variables inside the sandbox. Secrets should still be managed via Deploy’s secret substitution. |
32+
33+
34+
## Example configurations
35+
36+
### Allow outbound traffic to specific APIs
37+
38+
```tsx
39+
const sandbox = await Sandbox.create({
40+
allowNet: ["api.openai.com", "api.stripe.com"],
41+
});
42+
```
43+
44+
### Run in a specific region with more memory
45+
46+
```tsx
47+
const sandbox = await Sandbox.create({
48+
region: "ams",
49+
memoryMb: 2048,
50+
});
51+
```
52+
53+
### Keep the sandbox alive for later inspection
54+
55+
```tsx
56+
const sandbox = await Sandbox.create({ lifetime: "10m" });
57+
const id = sandbox.id;
58+
await sandbox.close(); // disconnect but leave VM running
59+
60+
// ...later...
61+
const reconnected = await Sandbox.connect({ id });
62+
```
63+
64+
### Provide default environment variables
65+
66+
```tsx
67+
const sandbox = await Sandbox.create({
68+
env: {
69+
NODE_ENV: "development",
70+
FEATURE_FLAG: "agents",
71+
},
72+
});
73+
```
74+
75+
## Tips
76+
77+
- Keep `allowNet` as narrow as possible to block exfiltration attempts.
78+
- Use metadata keys such as `agentId` or `customerId` to trace sandboxes in the
79+
Deploy dashboard.
80+
- Remember to call `await sandbox.kill()` (or rely on `await using`) when the
81+
sandbox is no longer needed; resources are billed until it shuts down.
82+
- For long-lived services, migrate from sandboxes to a Deploy app once the code
83+
stabilizes.

sandboxes/reference/expose_http.md

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
---
2+
title: "Expose HTTP"
3+
description: "Learn how to expose HTTP endpoints from Deno Sandboxes, enabling you to run web servers, APIs, and preview environments at the edge."
4+
---
5+
6+
You can run dev servers, preview apps, webhook receivers, or framework CLIs on
7+
any port and publish them instantly to a secure, random HTTPS URL.
8+
9+
```tsx
10+
await sandbox.writeTextFile(
11+
"server.js",
12+
"Deno.serve(() => new Response('Hello from Sandboxes'));",
13+
);
14+
const runtime = await sandbox.createJsRuntime({ entrypoint: "server.js" });
15+
const publicUrl = await sandbox.exposeHttp({ port: 8080 });
16+
console.log(publicUrl); // https://<random>.sandbox.deno.net
17+
```
18+
19+
The URL stays live for the sandbox lifetime, making it perfect for short-lived
20+
QA links or agent generated previews.
21+
22+
## When to expose HTTP
23+
24+
Expose HTTP whenever you need to share the sandbox with teammates, bots, or
25+
external services:
26+
27+
- Preview links for AI-generated web apps or instant demos
28+
- Webhook receivers that must be reachable from Stripe, GitHub, etc.
29+
- Framework dev servers (`next dev`, `astro dev`, `deno task dev`) that should
30+
be inspected from a browser
31+
- Temporary APIs, health checks, or observability probes
32+
33+
Because sandboxes are ephemeral, you do not need to manage DNS or certificates.
34+
Each call to `exposeHttp()` returns a unique hostname under `*.sandbox.deno.net`
35+
with TLS automatically configured.
36+
37+
## Step-by-step
38+
39+
1. **Start a server inside the sandbox.** Listen on any unprivileged port (e.g.,
40+
`3000`, `8080`).
41+
2. **Expose the port:** `const url = await sandbox.exposeHttp({ port: 3000 });`
42+
3. **Share or fetch from the URL.** Requests enter through Deploy’s global edge
43+
and are tunneled directly to your sandbox.
44+
45+
Multiple ports can be exposed simultaneously by calling `exposeHttp()` for each
46+
port. You can also re-use the same exposed URL after restarting your server, as
47+
long as the sandbox itself remains alive.
48+
49+
## Observing traffic
50+
51+
Requests routed through the exposed URL show up alongside your Deploy logs and
52+
traces. Use the dashboard to:
53+
54+
- Filter logs by sandbox ID or time range
55+
- Inspect request traces to track latency between the edge and your VM
56+
- Cancel or restart the sandbox if a preview misbehaves
57+
58+
## Security and networking
59+
60+
- Exposed URLs are long, random subdomains that are hard to guess.
61+
- TLS termination happens at the Deploy edge; traffic is encrypted end-to-end.
62+
- Combine `exposeHttp()` with `allowNet` so your sandbox can only reach the API
63+
hosts it truly needs.
64+
- Secrets are substituted only when the sandbox reaches an approved host, so
65+
dumping environment variables from inside the VM will never reveal them.
66+
67+
## Cleanup and limits
68+
69+
- An exposed URL stops accepting traffic when the sandbox lifetime ends or when
70+
you call `await sandbox.kill()`.
71+
- Call `exposeHttp({ port, keepAlive: true })` (coming soon) to opt into longer
72+
previews once available.
73+
- For persistent services, graduate the code into a Deploy app rather than
74+
relying on a long-running sandbox.
75+
76+
## Full example with a framework
77+
78+
```tsx
79+
import { Sandbox } from "@deno/sandbox";
80+
81+
await using sandbox = await Sandbox.create();
82+
83+
// Install dependencies
84+
await sandbox.writeTextFile(
85+
"package.json",
86+
JSON.stringify(
87+
{
88+
private: true,
89+
scripts: { dev: "next dev" },
90+
dependencies: {
91+
next: "^15.0.0",
92+
react: "^19.0.0",
93+
"react-dom": "^19.0.0",
94+
},
95+
},
96+
null,
97+
2,
98+
),
99+
);
100+
await sandbox.sh`npm install`;
101+
102+
// Start the dev server
103+
const server = await sandbox.spawn("npm", {
104+
args: ["run", "dev"],
105+
stdout: "inherit",
106+
stderr: "inherit",
107+
});
108+
109+
// Publish it
110+
const previewUrl = await sandbox.exposeHttp({ port: 3000 });
111+
console.log(`Preview ready at ${previewUrl}`);
112+
113+
await server.status; // keep running until the process exits
114+
```
115+
116+
This pattern lets agents or developers spin up high-fidelity previews, share
117+
them for feedback, and tear everything down with a single `Ctrl+C`.

0 commit comments

Comments
 (0)