forked from e2b-dev/E2B
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
6 changed files
with
173 additions
and
78 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
147 changes: 140 additions & 7 deletions
147
apps/web/src/app/(docs)/docs/sandbox/persistence/page.mdx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,16 +1,149 @@ | ||
# Sandbox persistence | ||
|
||
We're working on a feature that will allow you to persist sandboxes between runs. | ||
<Note> | ||
Sandbox persistence is currently in beta: | ||
1. You need to install the [beta version of the SDKs](#installing-the-beta-version-of-the-sdks) | ||
1. Consider [some limitations](#limitations-while-in-beta). | ||
1. The persistence is free for all users during the beta. | ||
</Note> | ||
|
||
In the meantime, you can mount cloud storage like Amazon's S3, Google Cloud Storage, or Cloudflare's R2 to the sandbox's filesystem. | ||
The sandbox persistence allows you to pause your sandbox and resume it later from the same state it was in when you paused it. | ||
|
||
**Prerequisites** | ||
- Famil | ||
This includes not only state of the sandbox's filesystem but also the sandbox's memory. This means all running processes, loaded variables, data, etc. | ||
|
||
## 1. Installing the beta version of the SDKs | ||
To use the sandbox persistence, you need to install the beta version of the SDKs. | ||
|
||
<CodeGroup> | ||
```bash {{ language: 'js' }} | ||
npm i e2b@beta | ||
``` | ||
|
||
## Amazon S3 | ||
```bash {{ language: 'python' }} | ||
|
||
## Google Cloud Storage | ||
# Install the latest beta version of the SDK on PyPi | ||
# https://pypi.org/project/e2b/#history | ||
pip install e2b-code-interpreter==1.1.0.b17 | ||
``` | ||
</CodeGroup> | ||
|
||
## Cloudflare R2 | ||
|
||
## 2. Pausing sandbox | ||
When you pause a sandbox, both the sandbox's filesystem and memory state will be saved. This includes all the files in the sandbox's filesystem and all the running processes, loaded variables, data, etc. | ||
|
||
<CodeGroup> | ||
```js | ||
import { Sandbox } from 'e2b' | ||
// or use Code Interpreter: https://github.com/e2b-dev/code-interpreter | ||
// import { Sandbox } from '@e2b/code-interpreter' | ||
// | ||
// or use Desktop: https://github.com/e2b-dev/desktop | ||
// import { Sandbox } from '@e2b/desktop' | ||
|
||
const sbx = await Sandbox.create() | ||
console.log('Sandbox created', sbx.sandboxId) | ||
|
||
// Pause the sandbox | ||
// You can save the sandbox ID in your database | ||
// to resume the sandbox later | ||
const sandboxId = await sbx.pause() // $HighlightLine | ||
console.log('Sandbox paused', sandboxId) // $HighlightLine | ||
``` | ||
```python | ||
from e2b import Sandbox | ||
# or use Code Interpreter: https://github.com/e2b-dev/code-interpreter | ||
# from e2b_code_interpreter import Sandbox | ||
# | ||
# or use Desktop: https://github.com/e2b-dev/desktop | ||
# from e2b_desktop import Sandbox | ||
|
||
sbx = Sandbox() | ||
print('Sandbox created', sbx.sandbox_id) | ||
|
||
# Pause the sandbox | ||
# You can save the sandbox ID in your database | ||
# to resume the sandbox later | ||
sandbox_id = sbx.pause() # $HighlightLine | ||
print('Sandbox paused', sandbox_id) # $HighlightLine | ||
``` | ||
</CodeGroup> | ||
|
||
|
||
## 3. Resuming sandbox | ||
When you resume a sandbox, it will be in the same state it was in when you paused it. | ||
This means that all the files in the sandbox's filesystem will be restored and all the running processes, loaded variables, data, etc. will be restored. | ||
|
||
<CodeGroup> | ||
```js | ||
import { Sandbox } from 'e2b' | ||
// or use Code Interpreter: https://github.com/e2b-dev/code-interpreter | ||
// import { Sandbox } from '@e2b/code-interpreter' | ||
// | ||
// or use Desktop: https://github.com/e2b-dev/desktop | ||
// import { Sandbox } from '@e2b/desktop' | ||
|
||
const sbx = await Sandbox.create() | ||
console.log('Sandbox created', sbx.sandboxId) | ||
|
||
// Pause the sandbox | ||
// You can save the sandbox ID in your database | ||
// to resume the sandbox later | ||
const sandboxId = await sbx.pause() | ||
console.log('Sandbox paused', sandboxId) | ||
|
||
// Resume the sandbox from the same state | ||
const sameSbx = await Sandbox.resume(sandboxId) // $HighlightLine | ||
console.log('Sandbox resumed', sameSbx.sandboxId) // $HighlightLine | ||
``` | ||
```python | ||
from e2b import Sandbox | ||
# or use Code Interpreter: https://github.com/e2b-dev/code-interpreter | ||
# from e2b_code_interpreter import Sandbox | ||
# | ||
# or use Desktop: https://github.com/e2b-dev/desktop | ||
# from e2b_desktop import Sandbox | ||
|
||
sbx = Sandbox() | ||
print('Sandbox created', sbx.sandbox_id) | ||
|
||
# Pause the sandbox | ||
# You can save the sandbox ID in your database | ||
# to resume the sandbox later | ||
sandbox_id = sbx.pause() | ||
print('Sandbox paused', sandbox_id) | ||
|
||
# Resume the sandbox from the same state | ||
same_sbx = Sandbox.resume(sandbox_id) # $HighlightLine | ||
print('Sandbox resumed', same_sbx.sandbox_id) # $HighlightLine | ||
``` | ||
</CodeGroup> | ||
|
||
## Sandbox's timeout | ||
When you resume a sandbox, the sandbox's timeout is reset to the default timeout of an E2B sandbox - 5 minutes. | ||
|
||
|
||
You can pass a custom timeout to the `Sandbox.resume()` method like this: | ||
|
||
<CodeGroup> | ||
```js | ||
import { Sandbox } from 'e2b' | ||
|
||
const sbx = await Sandbox.resume(sandboxId, { timeoutMs: 60 * 1000 }) // 60 seconds | ||
``` | ||
```python | ||
from e2b import Sandbox | ||
|
||
sbx = Sandbox.resume(sandbox_id, timeout=60) # 60 seconds | ||
``` | ||
</CodeGroup> | ||
|
||
## Network | ||
If you have a service (for example a server) running inside your sandbox and you pause the sandbox, the service won't be accessible from the outside and all the clients will be disconnected. | ||
If you resume the sandbox, the service will be accessible again but you need to connect clients again. | ||
|
||
|
||
## Limitations while in beta | ||
- It takes about 4 seconds per 1 GB RAM to pause the sandbox | ||
- It takes about 2 seconds to resume the sandbox | ||
- Soon, this will get to the same speed as calling `Sandbox.create()` | ||
- Sandbox can be paused up to 30 days |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,64 +1,19 @@ | ||
import clsx from 'clsx' | ||
|
||
const variantStyles = { | ||
small: '', | ||
medium: 'rounded-lg px-1.5 ring-1 ring-inset', | ||
} | ||
|
||
const colorStyles = { | ||
emerald: { | ||
small: 'text-brand-500 dark:text-brand-400', | ||
medium: | ||
'ring-brand-300 dark:ring-brand-400/30 bg-brand-400/10 text-brand-500 dark:text-brand-400', | ||
}, | ||
sky: { | ||
small: 'text-sky-500', | ||
medium: | ||
'ring-sky-300 bg-sky-400/10 text-sky-500 dark:ring-sky-400/30 dark:bg-sky-400/10 dark:text-sky-400', | ||
}, | ||
amber: { | ||
small: 'text-amber-500', | ||
medium: | ||
'ring-amber-300 bg-amber-400/10 text-amber-500 dark:ring-amber-400/30 dark:bg-amber-400/10 dark:text-amber-400', | ||
}, | ||
rose: { | ||
small: 'text-red-500 dark:text-rose-500', | ||
medium: | ||
'ring-rose-200 bg-rose-50 text-red-500 dark:ring-rose-500/20 dark:bg-rose-400/10 dark:text-rose-400', | ||
}, | ||
zinc: { | ||
small: 'text-zinc-400 dark:text-zinc-500', | ||
medium: | ||
'ring-zinc-200 bg-zinc-50 text-zinc-500 dark:ring-zinc-500/20 dark:bg-zinc-400/10 dark:text-zinc-400', | ||
}, | ||
} | ||
|
||
const valueColorMap = { | ||
GET: 'emerald', | ||
POST: 'sky', | ||
PUT: 'amber', | ||
DELETE: 'rose', | ||
} as Record<string, keyof typeof colorStyles> | ||
import React from 'react' | ||
|
||
export function Tag({ | ||
children, | ||
variant = 'medium', | ||
color = valueColorMap[children] ?? 'emerald', | ||
}: { | ||
// eslint-disable-next-line @typescript-eslint/ban-types | ||
children: keyof typeof valueColorMap & (string | {}) | ||
variant?: keyof typeof variantStyles | ||
color?: keyof typeof colorStyles | ||
children, | ||
}: { | ||
children: React.ReactNode | ||
}) { | ||
return ( | ||
<span | ||
className={clsx( | ||
'relative top-[1px] font-mono text-[0.625rem] font-semibold', | ||
variantStyles[variant], | ||
colorStyles[color][variant], | ||
'relative top-[1.5px] font-mono text-[0.625rem] font-semibold', | ||
'text-brand-400 bg-brand-1000 ring-1 ring-inset rounded-lg px-1.5 ring-brand-400/20', | ||
)} | ||
> | ||
{children} | ||
</span> | ||
) | ||
} | ||
} |