setup: runs, then reuses it on the next run — no pull, no install, no setup.
Quick Start
1
Add setup: to your environment file
Capture happens automatically — there is nothing to configure. Commit
.praisonai/environment.yaml with a setup: step.2
Run twice — the second run is fast
The first run installs and sets up, then commits the container. The second run starts straight from the capture.
3
Add refresh: for cheap incremental steps (optional)
refresh: runs only on a reuse — perfect for a re-editable install that picks up code changes.How It Works
The backend computes a reuse key from your definition, checks for a matching capture, and either reuses it or builds a fresh one.Reuse Decision
The backend follows this exact contract on every provision.- Compute
capture_key(config)→ look uppraisonai-env:{key}. - Hit (capture exists AND there was
setup:orpackages:to amortise) → start container from the capture; run onlyrefresh:(if any); updatelast_used; skip commit. - Miss (no capture, or nothing to amortise) → pull base image; install packages; run
setup:; commit topraisonai-env:{key}(if there was setup/packages). - Any commit failure → warn and degrade to ephemeral. The run never blocks.
- Any change to the definition → new
capture_key→ miss → full rebuild and new capture. The old capture stays until pruned.
The Two Hashes
You will see two different 12-char strings — one is safe to log, the other never leaves the machine.
Your
setup: runs with env values injected and may bake env-derived state into the filesystem (tokens, tenant config). A capture is only safe to reuse when those values match too — but the reuse key must never leak the secrets. So capture_key binds values (used as the tag) while definition_hash stays value-free (used as the loggable label).
Both are stable and order-insensitive: reordering keys or list entries yields the same hash.
refresh: — the incremental step
refresh: runs a cheap post-provision step only when the container was started from a capture.
- Accepts a
strorList[str]; a scalar is normalised to[scalar]. - Runs only on a reuse. It is skipped on a fresh (miss) provision because
setup:already runs there. - Fail-loud — a failing command raises, exactly like
setup:.
capture: — the opt-in flag
capture: gates capture on backends where a snapshot carries provider cost.
- Local docker capture always runs when there is work to amortise — docker ignores this flag.
- Cloud backends (where a snapshot may cost money) are opt-in and off by default; set
capture: trueto enable.
Managing Captures
Inspect and prune captures withlist_captures() and prune_captures().
~/.praisonai/environments/registry.json and records each capture:
ref tag suffix are the secret-aware capture_key; definition is the loggable definition_hash shown by list_captures(). prune_captures() removes captures whose last_used is older than max_age_s (default 14 days = 14 * 24 * 3600 seconds), deleting both the docker image and the registry entry, and returns the pruned keys.
Configuration Options
The two capture keys map ontoComputeConfig.metadata.
ComputeConfig reference
Full
ComputeConfig field referenceBest Practices
Add setup: before you add refresh:
Add setup: before you add refresh:
refresh: runs only on a reuse, so it is meaningful only once a capture exists. Start with setup:, then add refresh: for the cheap step you want on every rerun.Prune periodically
Prune periodically
The registry is unbounded by default. Call
prune_captures() in a scheduled job, or rely on the 14-day age-based cleanup.Cloud backends need capture: true
Cloud backends need capture: true
Local docker capture is free and always on. On cloud backends a snapshot may cost money, so set
capture: true to opt in.Errors
A failed capture degrades to ephemeral and logs a warning — the run still succeeds.Related
Environment File
The
.praisonai/environment.yaml reference — image, packages, setup, refresh, captureLocal Agent
Run the agent loop locally with any LLM and cloud-sandboxed tools
ComputeConfig reference
Full
ComputeConfig field reference
