diff --git a/packages/projects-docs/pages/sdk/_meta.json b/packages/projects-docs/pages/sdk/_meta.json
index 294371d7..1b46d56d 100644
--- a/packages/projects-docs/pages/sdk/_meta.json
+++ b/packages/projects-docs/pages/sdk/_meta.json
@@ -20,7 +20,7 @@
"type": "separator",
"title": "Privacy & Security"
},
- "sandbox-privacy": "Sandbox Privacy",
+ "hosts-privacy": "Hosts Privacy",
"preview-api-access": "Preview API Access",
"-- sandboxes": {
"type": "separator",
diff --git a/packages/projects-docs/pages/sdk/create-resume.mdx b/packages/projects-docs/pages/sdk/create-resume.mdx
index 62a033a8..92632e16 100644
--- a/packages/projects-docs/pages/sdk/create-resume.mdx
+++ b/packages/projects-docs/pages/sdk/create-resume.mdx
@@ -28,53 +28,38 @@ By default Sandboxes are `unlisted` and can be accessed and forked by anyone wit
If no argument is provided to `sandbox.create()`, we'll create a sandbox based on our [Universal](https://codesandbox.io/p/devbox/universal-pcz35m) template on CodeSandbox. You can also pass in a specific template id from [our collection of templates](/sdk/snapshot-library) or by creating your own snapshot using our [Snapshot Builder](/sdk/snapshot-builder). Additionally you can choose other sources like [Git](/sdk/sandbox#git) or [Files](/sdk/sandbox#files).
-### Create from Template
-
```ts
const sandbox = await sdk.sandboxes.create({
- source: 'template',
- id: 'some-sandbox-id'
-})
-```
+ id: 'some-sandbox-id',
-### Create from Git
+ // Optional properties
+ title: 'my-sandbox',
+ description: 'My sandbox',
+ tags: ['my-tag'],
-```ts
-const sandbox = await sdk.sandboxes.create({
- source: 'git',
- url: 'https://...',
- branch: 'main',
- templateId: 'optional-template-id-to-fork-from',
- // Optionally pass necessary git config for private repos etc.
- config: {
- accessToken: 'github-token',
- email: 'foo@bar.com',
- name: 'Foo Bar'
- },
- async setup(session) {
- await session.commands.run('pnpm install')
- await session.commands.run('pnpm run dev')
- await session.ports.waitForPort(5173)
- }
-})
-```
+ // Public, unlisted or private
+ privacy: 'private',
-
-It depends on the repo how you want to setup the sandbox. If it is configured with tasks you can run `session.setup.run()` to run the full setup, but if configured with a `.devcontainer` you want to restart the sandbox itself. Or you can do like the example just run some commands.
-
+ // Collection folder on Dashboard
+ path: '/users/some-user-folder',
-### Additional options
+ // Prefer closest cluster. Follows ISO 3166-1 alpha-2 codes.
+ ipcountry: "US",
-For any of the above sources you can also pass the following options:
+ // What VM Tier to use for the Sandbox
+ vmTier: VMTier.Pico,
-```ts
-const sandbox = await sdk.sandboxes.create({
- source: 'template',
- title: 'my-sandbox',
- description: 'My sandbox',
- tags: ['my-tag'],
- privacy: 'public'
- path: '/users/some-user-folder'
+ // How quickly the sandbox should hibernate after inactivity.
+ // Defaults to 300 seconds for free users, 1800 seconds for
+ // pro users. Maximum is 86400 seconds (1 day).
+ hibernationTimeoutSeconds: 120_000,
+
+ // Configure if Sandbox should wake up automatically on HTTP
+ // or requests or WebSocket connections
+ automaticWakeupConfig: {
+ http: true,
+ websocket: true
+ }
})
```
diff --git a/packages/projects-docs/pages/sdk/create-session.mdx b/packages/projects-docs/pages/sdk/create-session.mdx
index bf6c37b1..bdb3e468 100644
--- a/packages/projects-docs/pages/sdk/create-session.mdx
+++ b/packages/projects-docs/pages/sdk/create-session.mdx
@@ -12,10 +12,10 @@ There are currently two types of sessions. A "server session" and a "browser ses
```ts
const sandbox = await sdk.sandboxes.create()
-// Immediately consume the session on the server
+// Immediately create a session on the server
const session = await sandbox.connect()
-// Pass the browser session to the browser and connect
+// Or pass a browser session to the browser and connectToSandbox
const browserSession = await sandbox.createBrowserSession()
```
@@ -49,20 +49,31 @@ await session.fs.readTextFile('test.txt'); // This will work.
### Git
-Passing the users git access token allows the user to use git commands inside the sandbox. Their permission level will be inherited from the git token.
+Passing git details allows the user to use git commands inside the sandbox.
```ts
const sandbox = await sdk.sandboxes.create()
const session = await sandbox.connect({
- id: 'anonymous',
- git: {
- accessToken: 'github-token',
- email: "foo@bar.com",
- name: "Foo Bar"
- }
+ id: 'some-user-reference,
+ git: {
+
+ email: 'foo@bar.com',
+ accessToken: '...',
+ provider: 'github.com',
+
+ // Optional
+ name: 'Foo Bar',
+
+ // Optional for most providers
+ username: 'my-provider-username'
+ }
})
```
+
+It is highly recommended that Sandboxes where git credentials are used, are not exposed to the public. Even though we store the token in the isolated `~/private` folder, there are still some security concerns.
+
+
### Environment variables
If you pass environment variables, these variables will be available to the user inside the commands and terminals that they run in the Sandbox.
diff --git a/packages/projects-docs/pages/sdk/git.mdx b/packages/projects-docs/pages/sdk/git.mdx
index bf46314e..d9e5f263 100644
--- a/packages/projects-docs/pages/sdk/git.mdx
+++ b/packages/projects-docs/pages/sdk/git.mdx
@@ -13,21 +13,23 @@ When passing `git` information to the session, the session will be able to perfo
The Git API is available under `sandbox.git`.
+### Clone
+
+Clone a repository to the sandbox.
+
+```ts
+await session.git.clone('https://github.com/codesandbox/sandbox.git')
+```
+
+
+It depends on the repo how you want to setup the sandbox. If it is configured with tasks you can run `session.setup.run()` to run the full setup, but if configured with a `.devcontainer` you want to restart the sandbox itself.
+
+
### Status
Get the current status of the branch. You can also listen to status changes.
```ts
-const sandbox = await sdk.sandboxes.create()
-const session = await sandbox.connect({
- id: 'some-user-reference,
- git: {
- accessToken: 'classic_github_token',
- email: 'foo@bar.com',
- name: 'Foo Bar'
- }
-})
-
const status = await session.git.status()
console.log(status)
@@ -45,16 +47,6 @@ disposer()
Commit the current changes to the branch. This will do a `git add .` as well.
```ts
-const sandbox = await sdk.sandboxes.create()
-const session = await sandbox.connect({
- id: 'some-user-reference,
- git: {
- accessToken: 'classic_github_token',
- email: 'foo@bar.com',
- name: 'Foo Bar'
- }
-})
-
await session.git.commit("Some message")
```
@@ -63,15 +55,13 @@ await session.git.commit("Some message")
Push the current branch to the remote, this ensures the upstream is set.
```ts
-const sandbox = await sdk.sandboxes.create()
-const session = await sandbox.connect({
- id: 'some-user-reference,
- git: {
- accessToken: 'classic_github_token',
- email: 'foo@bar.com',
- name: 'Foo Bar'
- }
-})
-
await session.git.push()
```
+
+## Nested Git Repos
+
+You can also use `commands` to run git commands manually. This allows you to clone repos to nested folders and manage them as you see fit.
+
+```ts
+await session.commands.run('git clone https://github.com/codesandbox/sandbox.git ./nested-repo')
+```
diff --git a/packages/projects-docs/pages/sdk/sandbox-privacy.mdx b/packages/projects-docs/pages/sdk/hosts-privacy.mdx
similarity index 90%
rename from packages/projects-docs/pages/sdk/sandbox-privacy.mdx
rename to packages/projects-docs/pages/sdk/hosts-privacy.mdx
index 433fe07f..1a6204cc 100644
--- a/packages/projects-docs/pages/sdk/sandbox-privacy.mdx
+++ b/packages/projects-docs/pages/sdk/hosts-privacy.mdx
@@ -1,11 +1,11 @@
---
-title: Sandbox Privacy
-description: Learn about private sandboxes in CodeSandbox SDK.
+title: Hosts Privacy
+description: Learn about private hosts in CodeSandbox SDK.
---
import { Callout } from 'nextra-theme-docs'
-# Sandbox Privacy
+# Hosts Privacy
If a sandbox is private, its hosts won't be accessible unless a host token is provided.
@@ -14,7 +14,7 @@ You can obtain a host token by calling `sdk.hosts.createToken`. This token will
You create signed urls to your Sandboxes using the `hosts` API on the server:
```ts
-const hostToken = await sdk.hosts.createToken()
+const hostToken = await sdk.hosts.createToken('sandbox-id')
// Get a url for accessing port `5173`
const url = session.hosts.getUrl(hostToken, 5173)
@@ -30,7 +30,7 @@ This gives you low level management of your Sandboxes hosts. But you can also pa
```ts
const sandbox = await sdk.sandboxes.create()
-const hostToken = await sdk.hosts.createToken()
+const hostToken = await sdk.hosts.createToken(sandbox.id)
const session = await sandbox.connect({
id: 'some-user-reference',
@@ -53,7 +53,7 @@ cookie so subsequent requests from the same browser don't require the token.
You can set an expiration on the preview token when creating it:
```ts
-const hostToken = await sdk.hosts.createToken({
+const hostToken = await sdk.hosts.createToken('sandbox-id', {
expiresAt: new Date(Date.now() + 60 * 60 * 1000) // 1 hour
})
```
diff --git a/packages/projects-docs/pages/sdk/lifecycle.mdx b/packages/projects-docs/pages/sdk/lifecycle.mdx
index c30b2c24..4aa5089b 100644
--- a/packages/projects-docs/pages/sdk/lifecycle.mdx
+++ b/packages/projects-docs/pages/sdk/lifecycle.mdx
@@ -31,17 +31,55 @@ You will be able to connect to the Sandbox during this process and track its pro
```ts
const sandbox = await sdk.sandboxes.create()
-const setupSteps = sandbox.setup.getSteps()
+if (sandbox.bootupType === 'CLEAN') {
+ const session = await sandbox.connect()
+ const setupSteps = session.setup.getSteps()
-for (const step of setupSteps) {
- console.log(`Step: ${step.name}`);
- console.log(`Command: ${step.command}`);
- console.log(`Status: ${step.status}`);
+ for (const step of setupSteps) {
+ console.log(`Step: ${step.name}`);
+ console.log(`Command: ${step.command}`);
+ console.log(`Status: ${step.status}`);
+
+ const output = await step.open()
+
+ output.onOutput((output) => {
+ console.log(output)
+ })
+
+ await step.waitUntilComplete()
+ }
+}
+```
+
+If you want to show this setup as a client UX you can rather create a browser session and show the setup in the browser.
+
+```ts
+const sandbox = await sdk.sandboxes.create()
+if (sandbox.bootupType === 'CLEAN') {
+ const browserSession = await sandbox.createBrowserSession()
+
+ return browserSession
+}
+```
+
+And then in the browser:
+
+```ts
+import { connectToSandbox } from '@codesandbox/sdk'
+
+const session = await connectToSandbox({
+ session: browserSession
+})
+
+const setupSteps = session.setup.getSteps()
+
+for (const step of setupSteps) {
const output = await step.open()
+ // Show output in UI
output.onOutput((output) => {
- console.log(output)
+ // Show output in UI
})
await step.waitUntilComplete()
diff --git a/packages/projects-docs/pages/sdk/specs.mdx b/packages/projects-docs/pages/sdk/specs.mdx
index 0a70492d..e70aad6e 100644
--- a/packages/projects-docs/pages/sdk/specs.mdx
+++ b/packages/projects-docs/pages/sdk/specs.mdx
@@ -19,7 +19,6 @@ import { CodeSandbox, VMTier } from "@codesandbox/sdk";
const sdk = new CodeSandbox();
const sandbox = await sdk.sandboxes.create({
- source: 'template',
vmTier: VMTier.Small
});
```
@@ -28,7 +27,6 @@ You can also approximate the VM size:
```ts
const sandbox = await sdk.sandboxes.create({
- source: 'template',
vmTier: VMTier.fromSpecs({ cpu: 4, memGiB: 8 }),
});
```
diff --git a/packages/projects-docs/pages/sdk/template-library.mdx b/packages/projects-docs/pages/sdk/template-library.mdx
index c7ad5fcc..0ee80bbb 100644
--- a/packages/projects-docs/pages/sdk/template-library.mdx
+++ b/packages/projects-docs/pages/sdk/template-library.mdx
@@ -18,7 +18,6 @@ You can start from a template by passing the template id to the `sdk.sandboxes.c
```ts
const sandbox = await sdk.sandboxes.create({
- source: 'template',
id: 'some-template-id'
})
```
diff --git a/packages/projects-docs/pages/sdk/templates.mdx b/packages/projects-docs/pages/sdk/templates.mdx
index 148d1980..4d132d56 100644
--- a/packages/projects-docs/pages/sdk/templates.mdx
+++ b/packages/projects-docs/pages/sdk/templates.mdx
@@ -9,6 +9,10 @@ import { Callout } from 'nextra-theme-docs'
CodeSandbox has default templates that you can use to create sandboxes. These templates are available in the [Template Library](/sdk/template-library) and by default we use the "Universal" template. To create your own template you will need to use our CLI.
+
+To find inspiration check our template repository on GitHub: https://github.com/codesandbox/sandbox-templates
+
+
## Creating the template
Create a new folder in your project and add the files you want to have available inside your Sandbox. For example set up a Vite project:
@@ -28,6 +32,10 @@ Now we need to configure the template with tasks so that it will install depende
"dev-server": {
"name": "Dev Server",
"command": "npm run dev",
+ // We have automatic port detection, but configuring this will guarantee the port is assigned on the task
+ "preview": {
+ "port": 5173
+ },
"runAtStart": true
}
}
@@ -36,14 +44,18 @@ Now we need to configure the template with tasks so that it will install depende
The `setupTasks` will run after the Sandbox has started, before any other tasks.
+
+Do **NOT** start dev servers or other long running porcesses in the `setupTasks`. This will block the setup process and prevent the Sandbox from starting properly.
+
+
Now we are ready to deploy the template to our clusters, run:
```bash
-$ CSB_API_KEY=your-api-key npx @codesandbox/sdk build ./my-template --ports 5173
+$ CSB_API_KEY=your-api-key npx @codesandbox/sdk build ./my-template --privacy private --vmTier Micro --ports 5173
```
-The template will by default be built with `Micro` VM Tier unless you pass `--vmTier` to the build command.
+The tempalte default to a `Micro` VM Tier and privacy "unlisted". It is recommended to make templates private and evaluate setting a higher tier if you need the flexibility to adjust that later. When creating a Sandbox from a template you can always override the VM Tier.
This will start the process of creating Sandboxes for each of our clusters, write files, restart, wait for port 5173 to be available and then hibernate. This generates the snapshot that allows you to quickly create Sandboxes already running a dev server from the template.
@@ -51,12 +63,18 @@ This will start the process of creating Sandboxes for each of our clusters, writ
When all clusters are updated successfully you will get a "Template Tag" back which you can use when you create your sandboxes.
```ts
+import { VMTier } from '@codesandbox/sdk'
+
const sandbox = await sdk.sandboxes.create({
- source: 'template',
- id: 'some-template-tag'
+ id: 'some-template-id',
+ vmTier: VMTier.Pico
})
```
+## CI
+
+If you run the template builder on **CI** you can pass the `--ci` flag. This removes the interactive "failed sandbox" behavior and rather creates the template id regardless. The Sandbox that errored will show the error.
+
## Custom Docker Image
CodeSandbox uses [Dev Containers](https://containers.dev/) for configuring Docker or Docker Compose for an environment. You can configure Docker by creating a `.devcontainer/devcontainer.json` file inside your template folder with these contents: