Reference
Concepts
A Chalupa mental model: one source of truth, two lifecycles, and a push-based control plane.
Reviewed 2026-10-04
Chalupa avoids maintaining a second infrastructure definition alongside your
project. Compose continues to describe the services; chalupa.yml declares
only which part of the stack should travel and which adjustments the remote
environment needs.
Compose as the source of truth
The engine reads docker-compose.yml and derives:
- definitions for the selected services;
- ports that must cross the tunnel;
- named volumes used by those services;
- valid dependencies after unselected services are pruned.
Ports are not duplicated in a second list. If they change in Compose, the next preview picks up the change.
chalupa.yml as intent
chalupa.yml contains decisions specific to the remote environment:
- included services;
- overridden memory limits, variables, and commands;
- server region, size, and health check;
- persistent volume size;
- idle window;
- seed command;
- optional control-plane URL.
You should be able to integrate a new project by adding configuration, not a special branch inside the engine.
Ephemeral compute
The compute stack includes the server, cloud-init, and containers. It starts
with chalupa up and is destroyed with chalupa down. Both commands delegate
to the Taskfile, which owns the Pulumi lifecycle.
“Ephemeral” means replaceable, not unattended. While it exists, it:
- incurs compute cost;
- accepts SSH connections;
- exposes services only on loopback;
- emits heartbeats when the control plane is configured.
When it sinks, Chalupa retains the history and marks the environment as ended or without a signal, based on the evidence it received.
Persistent data
When you declare persist, block storage lives in a separate Pulumi stack,
conventionally named <stack>-data. The server mounts it and maps named
volumes to subdirectories.
By design:
chalupa downdestroys compute, not data;- a new
chalupa upcan mount the same volume again; - the Taskfile-only data deletion, never exposed by the CLI, is the only operation intended to delete it;
- storage can continue to incur cost after the server no longer exists.
This separation lets you restore a seed once and reuse it across multiple test cycles.
Data stores have separate owners
The word “database” can refer to different systems in a Chalupa deployment. Keep their ownership and credentials separate:
| Store | Owner | Purpose | Lifecycle |
|---|---|---|---|
| Project database | The target Compose project | Application data used by the demo or test. | Follows the selected Compose service and, when configured, the protected data volume. |
| Control-plane Postgres | Chalupa | Environment metadata, lifecycle events, bounded excerpts, telemetry, and artifact references. | Survives disposable compute and follows the control-plane retention policy. |
| Artifact storage | file.cheap | Complete private artifact bytes plus their integrity and retention records. | Independent from both Chalupa metadata and the project's data volume. |
Chalupa does not copy a Compose database into its control-plane Postgres. file.cheap does not share Chalupa's runtime or migration credential. Deleting one store must never be presented as cleanup for another.
The tunnel as a boundary
Chalupa rewrites every published port to bind to 127.0.0.1 on the server.
chalupa tunnel creates the matching ssh -L forwards and presents them as
localhost on your machine.
The model reduces the public attack surface, but it does not replace basic practices: protect SSH keys, keep secrets out of the repository, and review the inferred Compose output.
Agent and control plane
Vercel does not open SSH connections to servers or read local Pulumi state. The flow is push-based:
- cloud-init installs the agent;
- the agent observes containers, disk, uptime, and the idle window;
- it signs the payload;
- it posts to the ingest endpoint;
- the control plane validates, persists, and derives the visible state.
If the signal ages, the environment becomes stale or unknown. Chalupa does
not invent a healthy state.
Costs are estimates
The console combines the observed hourly rate for a resource with provider inventory and deployment history. Every monetary value is labeled estimated.
It shows these values separately:
- ephemeral compute;
- persistent storage;
- approximate month-to-date cost.
The provider invoice is authoritative. Price changes, taxes, credits, rounding, and unobserved resources can produce differences.
Suites and artifacts
A suite run describes its result, duration, metric, and environment. Large
files do not belong in the control-plane database: a run stores references to
a local fcheap stash, a committed private hosted file.cheap artifact, or a
stable external link.
This lets the control plane answer “what happened, and where is the evidence?” without becoming an incomplete object store.
Glossary
These words are used the same way on every page.
| Term | Meaning |
|---|---|
| Server (also box, compute) | The machine your provider creates for an environment, running your Compose services. A server is ephemeral: chalupa down destroys it. |
| Environment | One named deployment of a chalupa.yml: its name, or name-instance when you run several at once. It owns a server, optional volumes, a tunnel and a session, and it is what chalupa status reports. |
| Stack | A local Pulumi stack that owns resources. An environment has up to three: <name> for the server, <name>-data for the protected data volume and <name>-cache for the disposable cache. A fourth, <name>-backup, holds snapshot records when you enable backups. State is local to your machine. |
| Session | One time-bounded use of an environment, from launch to sink, with a deadline set by session.expiresAfterMinutes. The session: block in chalupa.yml configures it; the hosted console shows it as the session clock. |
| Golden image | A provider snapshot, built with chalupa snapshot build, that already has Docker and the tools installed, so a server booted from it skips package installation. You select it with compute.prebaked: true. |
| Cache | The disposable <name>-cache volume that keeps Docker's images and build cache across servers. It is not your data: it can be deleted and is refilled by the next build. The model cache for GPU inference is a separate, retained volume. |
| Data volume | The protected block storage in <name>-data. It survives chalupa down and bills until you delete it on purpose. |