Skip to main content
On this page

Boot a Python environment with snapshots

In this tutorial we will use the Deno Sandbox SDK to create a bootable volume, set up a development environment on that volume and snapshot it for future use. This workflow is ideal for languages like Python where environment setup can be slow, but the resulting filesystem can be reused across many sandboxes.

To use the Deno Sandbox SDK, you will need a Deno Deploy account and an access token. You can sign up for free and create an access token in the dashboard under SandboxesOverview+ Create Token.

Create a basic Deno application and install the @deno/sandbox SDK Jump to heading

First, create a new directory for this project and initialize a Deno application:

deno init my-snapshot-project
cd my-snapshot-project
deno add jsr:@deno/sandbox

1. Bake Python into a bootable volume Jump to heading

Create a new file setup_python.ts. This script will create a new volume, boot it, install Python and some popular libraries, then snapshot the volume for future use. The idea is to do the slow setup work once, then reuse the snapshot to boot new sandboxes in seconds.

In this file we will import the Sandbox SDK, create a client and set up a function to initialize a volume with Python:

setup_python.ts
import { SandboxClient } from "@deno/sandbox";
const client = new SandboxClient();

async function initSandbox() {
  // ... we'll fill this in next
}

Inside that function, we'll create a new volume with 10GB of space, give it a slug for easy reference and specify the region:

setup_python.ts (cont.)
const volume = await client.volumes.create({
  region: "ord",
  slug: "fun-with-python",
  capacity: "10GB",
});

Next we boot a sandbox with that volume as its root filesystem. The await using pattern ensures that the sandbox is automatically cleaned up when we're done with it:

setup_python.ts (cont.)
await using sandbox = await client.sandboxes.create({
  region: "ord",
  root: volume.slug,
});

We install Python and some common scientific libraries using apt and pip. Note the use of --break-system-packages with pip -- since this sandbox owns the whole system, we can safely bypass pip's usual protections against messing with system files:

setup_python.ts (cont.)
await sandbox.sh`sudo apt-get update -qq`;
await sandbox
  .sh`sudo apt-get install -y python3 python3-pip python3-venv python3-dev build-essential`;

await sandbox.sh`sudo pip3 install --break-system-packages \
    requests \
    httpx \
    numpy \
    pandas \
    python-dotenv`;

console.log("Verifying Python installation...");

await sandbox.sh`python3 --version`;
await sandbox.sh`pip3 --version`;

The final step of this function is to return the volume.id so that we can pass it to the snapshot step:

setup_python.ts (cont.)
return volume.id;

(Remember to close the function with a } after this return.)

Next we call this function and snapshot the resulting volume. This will create a new snapshot with the slug fun-with-python-snapshot that we can boot from later:

setup_python.ts (cont.)
const volumeId = await initSandbox();

console.log("Snapshotting the volume...");

const snapshot = await client.volumes.snapshot(volumeId, {
  slug: "fun-with-python-snapshot",
});

console.log("Created Python snapshot " + snapshot.id);

Run the script with network and environment access so it can reach the Sandbox API:

deno run -N -E setup_python.ts

Snapshots are read-only. Any sandbox that mounts this slug now sees a filesystem with Python and the listed packages ready to go.

Boot directly from the snapshot Jump to heading

Create a new file called use_python.ts. This script will boot a new sandbox directly from the snapshot we created in the previous step, without running any setup commands. This demonstrates how you can reuse a snapshot to skip setup and get straight to running your code.

We start by importing the SDK and creating a client, just like before:

use_python.ts
import { Client } from "@deno/sandbox";

const client = new Client();

Then we create a new sandbox, but this time we specify the snapshot slug in the root field instead of a volume:

use_python.ts (cont.)
await using sandbox = await client.sandboxes.create({
  region: "ord",
  root: "fun-with-python-snapshot",
  port: 8000,
  timeout: "30m",
});

We've given this sandbox a 30-minute timeout and exposed port 8000, which our Python app will use later.

For now, we'll put in a placeholder string, which we'll replace with our actual Python app code in a moment, and set it up to be written into the sandbox filesystem at /tmp/app.py:

use_python.ts (cont.)
const appCode = `# Python app code goes here`;

await sandbox.fs.writeTextFile("/tmp/app.py", appCode);

Finally we spawn the Python app in the background and print the public URL where it's reachable. The await p.output() line keeps the script running so the sandbox doesn't immediately shut down:

use_python.ts (cont.)
const p = await sandbox.sh`python3 /tmp/app.py`.spawn();

console.log("\nMandelbrot Explorer running at", sandbox.url);

await p.output();

Now let's fill in appCode with a simple Python HTTP server that renders a colorful ASCII Mandelbrot fractal using numpy. This is just an example to showcase the scientific libraries we installed in the snapshot -- you can replace it with any Python code you like!

Grab the python code from the github repo and paste it into the appCode string in use_python.ts.

Now we're ready to run this script:

$ deno run -A use_python.ts

Open the logged URL in your browser and start zooming; every tile is powered by the numpy installation you baked into the snapshot earlier!

Iterate, branch, or clean up Jump to heading

  • Need to tweak the environment? Create a writable fork from the snapshot, boot it, change packages, then snapshot again:

    const fork = await client.volumes.create({
      region: "ord",
      slug: "python-sandbox-fork",
      capacity: "10GB",
      from: "fun-with-python-snapshot",
    });
    
  • Done with a snapshot? Remove it to free space:

    await client.snapshots.delete("fun-with-python-snapshot");
    

🦕 With this workflow you can hand teammates, AI agents or CI jobs a slug that boots a fully stocked development environment in seconds. Install once, snapshot, and skip setup forever.

Did you find what you needed?

Privacy policy