Skip to content

Ask AI

Ask anything about Destesi — setup, products, APIs.

Powered by Claude. Answers may be wrong — always verify against the docs.

Concepts

Preview turns a docker-compose stack and a pull request into a live, isolated environment. This page covers the mental model; the reference has the exact commands, fields, and env vars.

A preview is a running copy of your application, scoped to one pull request (or one ad-hoc creation), reachable at a stable URL. It consists of:

  • Your app, run from your docker-compose file inside an isolated pod.
  • A write-isolated Snap branch of your database, injected as a connection string.
  • An overlay proxy in front of the app that injects the Destesi shell UI without touching your code.

The compose file in the pull request is the source of truth. Change a service in the PR and the preview changes with it — there is no separate environment definition to keep in sync.

The mental model: the PR is the environment

Section titled “The mental model: the PR is the environment”

Most preview tools deploy a build artifact to shared staging, where data drifts and one PR’s changes bleed into another. Preview inverts that:

  • One environment per pull request. Identity is (workspace, pull request number). Pushing a new commit redeploys the same preview in place rather than stacking up new ones.
  • The database is forked, not shared. Each preview gets its own copy-on-write branch of your real data. Reviewers see realistic state; writes during review stay contained and vanish when the preview is torn down.
  • The source is never written to. Snap’s branch is copy-on-write — your production database is read from to seed the branch and never mutated.

When you create a preview (via the CLI, a GitHub Actions workflow, or the web dashboard), a controller picks up the work and runs this pipeline:

  1. Resolve the source. For a GitHub source, the controller fetches the repository archive using your workspace’s GitHub token from Connect. For a local source (--from-dir), the CLI tars the directory and uploads it.
  2. Fork the database branch. If the stack needs a database, the controller forks a Snap branch from the environment’s remote (or the one you named) and waits for it to be ready.
  3. Resolve environment templates. Declared env values like ${postgres.dsn} are resolved server-side against the freshly-forked branch. Unresolved references fail the preview fast.
  4. Provision the pod. A pod runs your docker compose up --build, fronted by the overlay proxy and exposed on a stable address.
  5. Promote to healthy. The preview becomes healthy only once it is actually reachable over HTTP — not merely scheduled.

Dev mode runs your preview from the development stack with hot reload, so source edits — your own, or ones the preview agent pushes — take effect in the running preview without a full image rebuild. Turn it on with the Dev mode checkbox in the create form, or --dev-mode on dst preview create / upsert.

It requires a docker-compose.dev.yml in the repository: dev mode tells the runner to prefer that file (the development stack, with its bind-mounted source and watch command) over the production compose. If the file isn’t present, the preview fails fast rather than silently falling back.

When to use it:

  • Use it for iterative review — when you expect to push fixes through the preview agent or want the preview to track an actively-changing branch.
  • Leave it off for a clean, build-once snapshot of the PR as it stands. The default build path runs docker compose up --build, which produces a more production-like preview.

A preview running in dev mode is marked with a dev mode badge in the dashboard.

A preview moves through a small state machine:

pending → building → starting → healthy

These are the exact status labels you’ll see on the preview’s status badge in the dashboard.

  • pending (transient) — created and queued, waiting for the controller to claim it.
  • building (transient) — the controller has claimed the work: fetching the source archive, forking the Snap branch, resolving env templates, and building images.
  • starting (transient) — images are built and containers are coming up behind the overlay proxy; the preview is not yet answering over HTTP.
  • healthy — reachable over HTTP. This is a real reachability check, not just “pod scheduled”.
  • failed (terminal) — a build, run, or configuration error. The reason is on the preview’s last_error.
  • deleted (terminal) — torn down; the pod and the forked branch are cleaned up.

A preview can return to pending when you redeploy or push a new commit — the same record is reused, so it cycles back through building and starting rather than creating a new preview.

A preview is only as useful as its data. Booting an empty database next to the app produces a preview that “renders” but can’t be exercised. Preview leans on Snap for this:

  • Copy-on-write branching means a fork is fast and cheap regardless of database size — you’re not dumping and restoring gigabytes per PR.
  • Write isolation means a reviewer can create, edit, and delete freely without corrupting the source or colliding with another preview.
  • Per-preview teardown discards the branch with the pod, so previews leave no residue.

This is why connecting a Snap remote is part of getting started — it’s the substrate the preview forks from.

The overlay proxy fronts every preview and serves a shell UI under /.destesi/*. It exists so a reviewer can do a full review — read the change, click through the app, and ship a fix — from the preview URL alone:

  • A change-summary modal orients the reviewer on first load.
  • The preview agent can edit code and push back to the branch using the GitHub App installation token. Branch protection and CODEOWNERS still apply, so the agent can’t bypass your governance.
  • OAuth passthrough lets Google, GitHub, Microsoft, and Slack logins work on ephemeral preview URLs against a single pre-registered callback, so you don’t register a redirect URI per PR.

The overlay is injected by the proxy; your application code is unchanged and unaware of it.

Preview is a peer product in the Destesi suite — one login, one workspace, opened from the 9-dot launcher.

  • Workspaces — the unit of collaboration. Every preview, key, and remote is workspace-scoped.
  • Accounts & SSO — a single session follows you across products.
  • Connect — third-party credentials (your GitHub connection) are added once per workspace and fetched by products at call time, never stored per-app.
  • Snap — the database branching engine each preview forks from.