Preview
Give every pull request its own running environment. Preview takes your docker-compose stack, forks an isolated branch of your real database, and serves the result at a stable URL — so reviewers click through the actual app with real data instead of guessing from a diff.
Why Preview
Section titled “Why Preview”- Real data, never touched. Each preview forks a copy-on-write Snap branch of your database. Writes stay inside the preview; the source database is never written to.
- No drift. The
docker-composefile in the pull request is the environment definition. What the PR proposes is what gets deployed. - Review without checking out. A reviewer opens one URL and uses the app. On first load they see an AI-generated change summary; an in-page agent can edit, commit, and push fixes straight back to the branch.
Fastest path to first value
Section titled “Fastest path to first value”The quickest way to see a preview is to point Preview at a local directory that contains a docker-compose.yml. No GitHub wiring, no CI — same pipeline, same database fork, same overlay.
-
Install the CLI and sign in.
Terminal window curl -fsSL https://get.destesi.io/install.sh | shdst loginThis installs the
dstbinary. See the CLI docs for shell completion and configuration. -
Register a database to fork from.
Preview forks a Snap branch per preview, so it needs a source to fork from. Add your database as a Snap remote once:
Terminal window dst snap remote postgres postgresql://user:pass@db-host:5432/app# Remote added: conn_abc status=healthy -
Create a preview from a local directory.
Terminal window dst preview create \--from-dir ./app \--from-remote conn_abc \--env 'DATABASE_URL=${postgres.dsn}' \--env-secret NEXTAUTH_SECRET=$(openssl rand -hex 32)# Preview created: prev_abc status=pending--from-dirtars the directory and uploads it.${postgres.dsn}is resolved server-side to the forked branch’s connection string — see environment templates. -
Wait for it to come up, then open the URL.
Terminal window dst preview wait prev_abc --timeout 10m# http://localhost:30452dst preview waitblocks until the preview is reachable over HTTP, then prints the URL. First builds of a fresh repo can take several minutes while images pull anddocker compose up --buildruns.
From pull request to preview
Section titled “From pull request to preview”Once you’re happy with the local loop, wire Preview into your pull requests so every PR gets an environment automatically.
-
Connect GitHub in Connect. Authorize the Destesi GitHub App for your repositories once, at connect.destesi.io. Products fetch the GitHub token from Connect at call time — you never paste a token into CI. See Connect for the one-time setup.
-
Mint a CI-scoped key. Don’t use your personal token in CI — mint a preview-runner key scoped to
preview:writeon a single workspace:Terminal window dst api-key create --preview-runner --label github-actions -o token \| xargs -I {} gh secret set DESTESI_API_KEY --body {}A leaked preview-runner key can’t reach your snaps, other workspaces, or the rest of the suite.
-
Add the workflow. A two-job GitHub Actions workflow upserts a preview on
pull_request: opened/synchronizeand tears it down onclosed. The fullpreview.ymlis in the reference.
The review loop
Section titled “The review loop”Every preview is fronted by an overlay proxy that injects a small shell UI at /.destesi/* — no changes to your app:
- Change-summary modal on first load (per commit): PR title, an AI-generated 2–3 sentence summary, and a per-file changed list.
- Preview agent (
Cmd+Shift+A): a chat that can read files, make edits, thengit commitandgit pushback to the PR branch. Your CI redeploys the preview on the new commit. - Live dev tools: pod logs (
Cmd+Shift+L), inspect element (Cmd+Shift+I), and a network tap (Cmd+Shift+N).
The agent pushes with the same GitHub App installation token the runner clones with — branch protection, required reviews, and CODEOWNERS all still apply.
The Operations Workbench
Section titled “The Operations Workbench”The overlay is for the person reviewing one pull request. The Operations Workbench — the Preview web app itself — is for the person watching all of them. It is a list, an inspector, and a diagnostics surface side by side, so you can find a misbehaving preview and read its logs without leaving the page.
The list filters by state with live counts: All active, Ready, In progress, Failed, and Expiring soon (anything inside four hours of its TTL). Search matches name, repository, branch, and pull-request number or title, and a repository dropdown narrows to one repo. Each row carries a status medallion and one context line that tells you what you actually need: the error message if the preview failed, the current build phase if it’s still working, otherwise repository, branch, and short commit.
The inspector opens beside the list (below lg it becomes a full-screen sheet) with three tabs:
- Overview — the public URL with a copy button, the source (kind, repository, branch, commit), the database (which remote or parent branch it forked from, and whether the fork exists yet), the exposed service and port, configuration chips for dev mode / OAuth / env-var count, and the timestamps including when it expires.
- Timeline — the preview’s events in order: created, build started, build failed, healthy, redeployed, phase changes, and the controller’s own decisions. This is where a message like
skipped snap fork (no source configured)shows up. - Logs — a live tail of container output, with a source dropdown for the runner, the Docker daemon, the overlay, or any individual compose service.
Both panels stay mounted once opened, so switching tabs never drops a running log stream. Redeploy and Delete live in the inspector’s footer, delete kept in its own danger box.
The app defaults to a dark theme with a light theme available from the toggle in the navigation bar.
Environment templates
Section titled “Environment templates”Because the database branch is created after you submit the preview, you don’t write its connection string by hand. Declare templates in your env list and Preview resolves them server-side against the forked branch:
| Template | Resolves to |
|---|---|
${postgres.dsn} |
Full connection string for the forked branch |
${postgres.host} |
Branch host (in-cluster address for the running app) |
${postgres.port} |
Branch port |
${postgres.user} / ${postgres.password} |
Branch credentials |
${postgres.database} |
Branch database name |
${postgres.sslmode} |
sslmode |
An unknown namespace or field fails the preview fast with a clear error — never an empty string. Full list and rules in the reference.
How it fits the suite
Section titled “How it fits the suite”Preview is one peer product in the Destesi suite. One login, one workspace, opened from the 9-dot launcher.
- Workspaces — every preview is scoped to a workspace; that’s where your data and members live.
- Accounts & SSO — one sign-in follows you across products.
- Connect — your GitHub connection lives here, added once per workspace.
- Snap — the copy-on-write database engine Preview forks a branch from.