Which one do I want?
Three things to do with a snapshot, and they get mixed up because they all come from the same one.- Resume gives you your Box back. Same Box, same id, new machine underneath.
- Fork gives you a second Box holding a copy of the filesystem as it is right now. The original keeps running, untouched.
- Template freezes a named copy that stays put. You deploy from it whenever you like, and it still works long after the Box it came from is gone.
What is captured
Captured
/home/user: your code, files, and configDocker named volumes (/var/lib/docker/volumes)Your changes under /etc, /usr, /opt, /root, /srv, cron tables, and the apt package database: installed packages, systemd services, system configNot captured
The base OS and pre-installed tooling, which ship with the machine imageMachine identity: hostname, network config, SSH host keysRunning processes, memory, open ports
Excluding files with .boxignore
Build artifacts and dependency trees are worth nothing in a snapshot and slow every restore down. Nothing is left out of a snapshot unless you ask for it: write a .boxignore and every capture from the next one on obeys it.
.boxignore in a repo covers that repo and one in your home directory covers the whole Box. It is looked for up to six directories below your home directory, and the search skips node_modules, .next, target and vendor — put the file at the root of the tree you want skipped, not inside it.
Your .gitignore is not used. It answers “do not commit this”, which is a different question from “it is safe to lose this on resume” — a build cache is routinely both. It is also not yours at all in a tool you installed as a git clone: ~/.nvm’s own .gitignore excludes v*, which is every node version you have installed.
.git is always captured, since it is the one thing you cannot regenerate.
Boxes created before this file was renamed still honour the old .oneignore name.
Automatic snapshots
Snapshots are incremental: the first is a full base, each later one stores only what changed, compressed, content-addressed and deduped against the base image. They are taken every minute while the Box is ready or idle, and a final one when it stops. If that final snapshot fails, the stop is aborted and the machine keeps running, so stopping can never lose data. Stopping at any moment is safe; the snapshot is always complete. Snapshots are kept for the life of the Box. Its latest can be resumed or forked whether it stopped yesterday or months ago. Superseded ones are cleaned up continuously as new ones are taken.Resume
Brings the same Box back on a fresh machine, from its latest snapshot. Same Box id, same filesystem, new hardware.box stop. Shrinking to a smaller machine is refused if the Box holds more data than it can take, and the Box is left untouched. See Machines.
Omit ttlSeconds to keep the Box’s current lifetime. Pass null (--no-auto-stop) to switch auto-stop off entirely.
Fork
Clones a Box from its latest snapshot into a new, independent Box. The source keeps running and is never modified.env. It also inherits the source’s exact environment version, so a fork never picks up configuration its source never had. See Environments.
A fork does not inherit the source’s lifetime. It defaults to 1 hour, so a fork of a Box with auto-stop switched off is not itself left running forever. Pass ttlSeconds (or --no-auto-stop) when you want something else.
Use fork for a throwaway copy right now: a second branch of work, a risky experiment, one machine per user of your product. If you find yourself forking the same Box repeatedly, make it a template instead.
Template Boxes
When many Boxes need the same stack pre-installed, build it once, save it under a name, and deploy from that name instead of installing on every fresh Box.- Create a Box and install everything: runtimes, packages, your app or daemon.
- Save it:
box snapshot <id> <name>. That freezes the Box’s disk at this moment under the name. - For each new Box:
box new --from <name>. Deploys are usable in a few seconds, at roughly constant cost regardless of how much the template holds.
from is a reserved word in Python, so build that one request with from_dict as above rather than keyword arguments.box snapshots.
Templates are not environments
A template holds the disk. An environment holds the configuration. They are different tools and most setups use both.
If you would put it in a Dockerfile it belongs in a template; if you would put it in a
.env it belongs in an environment. Compose them:
Updating a template
Save the same name again: resume the Box (or any Box set up the way you want), update the stack, and runbox snapshot <id> <name> with the existing name. The name points at the new state and the old artifact is released. Boxes already deployed from it are unaffected. If a re-save fails, the name keeps deploying the last good save.
What happens on restore
A resume, fork or deploy is usable in a few seconds, whatever the Box holds. The full file tree is there immediately, every file is readable on demand, and content finishes downloading in the background. Permissions, ownership, timestamps and extended attributes come back with your files, and on directories too. Two details are worth knowing:- Extended attributes on a file become readable once that file’s content has arrived. Directories carry theirs from the moment the Box is up.
- Directory modification times are restored once the background download finishes rather than immediately, because writing a file into a directory updates that directory’s timestamp, so setting it any earlier would just be overwritten.
Warming for faster first boots
A Box records the order in which files are first opened while it is starting up, and keeps that order in.ascii/playbook.json. On the next start those files are fetched first, so your app reaches a working state before the rest of the disk has arrived. The playbook is an ordinary file, so it is captured into the snapshot and every fork or deploy inherits it.
Recording only happens while a Box is starting up from a snapshot, so the order matters:
1
Start the Box from a snapshot
Resume a stopped Box, or deploy one from the template you are about to update. A Box created from scratch has nothing to record against.
2
Boot your app straight away
Run the normal startup, right away, while the Box is still filling in. Every file it opens is recorded in the order it asks for them. Files opened later, once the Box has finished filling in, are not recorded.
3
Let it finish, then save
The playbook is written when the Box finishes filling in. Save after that, or the run you just did is not in the template.
Retention
By default, snapshots are kept for the life of the archived Box: its latest snapshot can be resumed or forked whether it stopped yesterday or months ago. Superseded snapshots are cleaned up continuously as new ones are taken. Permanent deletion is different from archive. Deleting a Box or snapshot returns a background operation and makes the target unavailable; it cannot be resumed. Named snapshots remain independent of their source Box. When you remove one, its backing data is scheduled no earlier than six hours later so already-issued signed upload URLs expire first. With zero data retention, archived Box data and named snapshots are queued for deletion instead of retained.Inspect and download
pull writes two subfolders, home_user/ (your /home/user) and docker/ (named volumes), reflecting exactly the files that were live at that snapshot. There is no SDK equivalent of pull: it is getSnapshotDownload plus local reassembly.
Browse the same tree, and download files from it, on the Snapshots tab of the dashboard.
See the Snapshots API for the full surface.
Deleting a Box’s snapshots
Stopping a Box keeps its snapshots, that is the whole point of stopping. Deleting a Box throws them away.X-Ascii-Confirm-Delete must equal the Box id exactly, or the request is refused with 409 and nothing is deleted. See Data retention and deletion for the operation you get back and how to poll it.
You can also delete a Box from the ⋯ menu on its row in the dashboard.
The Box leaves your account immediately; the snapshot data goes once the machine has finished shutting down.
What survives, and why. Snapshots are shared: a fork, a resume and a deploy from a template all read the same physical objects as the Box they came from. Deleting a Box therefore only removes the snapshot data nothing else is using. Kept are:
- chains a Box forked or resumed from this one still restores from
- named snapshots saved from this Box, which are meant to outlive it. Delete those with
box snapshot rm <name>when you want the bytes gone.