Snapshots & forks
A snapshot is a sandbox’s disk saved under a name: installed packages, a cloned repository, a warm build cache. A sandbox started from it begins exactly there. A fork copies one sandbox into a new one from its last snapshot, which Boat takes now and then while it runs, and every time it stops.
Every sandbox starts from the same disk
Section titled “Every sandbox starts from the same disk”The setup runs once, at deploy. Every sandbox after it starts with the work already done, and changes only its own copy:
Build a snapshot from commands
Section titled “Build a snapshot from commands”List the commands that set it up:
import * as Boat from "@alchemy.run/boat";
export const Golden = Boat.Snapshot("Golden", { run: [ "git clone https://github.com/alchemy-run/alchemy ~/alchemy", "cd ~/alchemy && pnpm install", ],});Alchemy starts a sandbox with none of your account’s secrets, runs the commands in order, saves its disk and deletes the sandbox. A command that exits non-zero fails the deploy with SnapshotSetupFailed. A deploy runs them again only when the commands, env, cwd, type or from change, and saves the new disk under the same name. Destroying the resource deletes it.
Build one snapshot on another with from:
export const Tools = Boat.Snapshot("Tools", { run: ["npm i -g pnpm"] });export const Golden = Boat.Snapshot("Golden", { from: Tools, run: ["pnpm dlx playwright install"] });Start sandboxes from a snapshot
Section titled “Start sandboxes from a snapshot”A declared sandbox starts from a snapshot with snapshot:
export const Box = Boat.Sandbox("Box", { snapshot: Golden });When the snapshot is rebuilt, the sandbox is replaced, so it starts from the new disk.
So do the sandboxes a binding creates, when you bind the snapshot:
const sandboxes = yield* Boat.CreateSandbox(Golden);const sandbox = yield* sandboxes.create({ autoStop: "10 minutes" });A sandbox from a snapshot takes its machine size unless you pass type.
Fork a sandbox into a copy
Section titled “Fork a sandbox into a copy”fork starts a copy of a sandbox your code created, from its last snapshot:
yield* sandbox.stop(); // stopping takes a snapshotconst copy = yield* sandbox.fork({ autoStop: "10 minutes" });yield* sandbox.resume();Before a sandbox has a snapshot, fork fails with ForkNeedsSnapshot. Boat never copies labels onto a fork; Alchemy adds the host’s alchemy.* labels again.
Save a running sandbox under a name
Section titled “Save a running sandbox under a name”A handle saves its sandbox under a name of your own, and waits until it’s ready:
const saved = yield* sandbox.snapshot("after-install");Snapshots your code saves aren’t deleted with the Stack.
To give sandboxes variables, secret files and credentials, see Environments & secrets.