Operating model
Lifecycle
Operate an environment through explicit steps and retain data only for as long as you need it.
Reviewed 2026-07-23
The lifecycle is split into local validation, optional data preparation, compute, access, and shutdown. Tasks encapsulate the operational logic; do not reproduce their Pulumi commands by hand.
At a glance
| Stage | Command | Changes the cloud | Effect |
|---|---|---|---|
| Validate | task validate CONFIG=<path> |
no | Checks types, tests, inferred Compose, and ports. |
| Prepare data | task data-up CONFIG=<path> |
yes | Creates the persistent volume. |
| Launch | task up CONFIG=<path> |
yes | Creates ephemeral compute. |
| Connect | task tunnel CONFIG=<path> |
no | Keeps local SSH tunnels open. |
| Seed | task seed CONFIG=<path> |
changes data | Runs the seed through the tunnel. |
| Inspect | task status CONFIG=<path> |
read-only | Summarizes the declared environment. |
| Sink | task down CONFIG=<path> |
yes | Destroys compute only. |
| Delete data | task data-nuke CONFIG=<path> |
yes, irreversible | Destroys the persistent volume. |
Preview
The preview runs the same inference as the Pulumi program without creating resources:
export DEMO_CONFIG="$PWD/chalupa.yml"
cd "$CHALUPA_HOME"
task validate CONFIG="$DEMO_CONFIG"
Stop if a service is missing, an unexpected port appears, or TypeScript fails.
Prepare the data stack
This step applies only when chalupa.yml declares persist:
task data-up CONFIG="$DEMO_CONFIG"
Run it once per volume. The data stack has a separate name so destroying compute does not include it.
Launch
task up creates billable resources:
task up CONFIG="$DEMO_CONFIG"
The task loads secrets at runtime, selects the local Pulumi backend, creates the
stack, and delivers cloud-init. task up can finish before the containers and
health check are ready. Confirm readiness with the first heartbeat and through
the tunnel.
Connect and work
Keep the tunnel open in one terminal:
task tunnel CONFIG="$DEMO_CONFIG"
In another terminal, you can run:
task seed CONFIG="$DEMO_CONFIG"
bun run test:e2e
Connections arrive at localhost; the SSH process is the access boundary.
Closing the tunnel does not destroy the environment. Chalupa can show an
observed idle window to remind you to sink it.
Sink
When the work is complete:
task down CONFIG="$DEMO_CONFIG"
This destroys the droplet and stops its estimated compute cost. The persistent volume remains intact and can continue to incur estimated storage cost.
If the environment uses the control plane, the task captures its provider ID
before the destroy. Only after Pulumi completes successfully does it send a
signed, idempotent sunk event. A telemetry failure does not undo the
destruction: the task emits a warning. Reconciliation may recover the state
only when Chalupa already knows the deployment; a short-lived cycle missed
between inventory polls is not observable. Verify the state manually and
treat the provider invoice as authoritative. Chalupa retains events and suite
runs so the resource's absence does not erase operational context.
Idle window
With idleShutdownMinutes, the agent reports idle checks and the control plane
derives an informational window. Use the warning as a prompt to run
task down.
The current version does not delete the droplet automatically, and cloud-init never receives a deletion credential. Automatic sinking through a trusted worker is future work.
Delete data
task data-nuke is an independent action:
task data-nuke \
CONFIG="$DEMO_CONFIG" \
CONFIRM_DATA_NUKE=demo-harbor
It deletes the block storage volume. It is not part of the normal shutdown
path and must not be used merely to “clean up” an environment. Confirm the
backup, target, and stack name before you run it. The confirmation value must
exactly match the name in chalupa.yml; otherwise the task refuses to
unprotect or destroy the data stack.