Preview environments
Clank previews are temporary deployments attached to a production project. Each preview is a real isolated project with its own URL, SQLite database, migration history, releases, secrets, jobs, logs, metrics, backups, and project scoped tok
Clank previews are temporary deployments attached to a production project. Each preview is a real isolated project with its own URL, SQLite database, migration history, releases, secrets, jobs, logs, metrics, backups, and project-scoped tokens.
The important default is absence: creating a preview does not copy production data or secrets. An application must populate test data explicitly. This prevents a routine branch deploy from turning into an unreviewed production-data export.
Deploy a preview
Link the directory to its production project once, then name the preview:
clank preview deploy feature-auth
clank preview deploy pull-482 --ttl=48
clank preview list--ttl is an integer number of hours. The hosted defaults are seven days with a maximum of 30 days. Deploying the same normalized name again reuses its isolated environment, publishes a new atomic release, and refreshes its expiration. It never changes .clank/project.json, so the directory remains linked to production.
For agents and CI:
clank preview deploy pull-482 --ttl=24 --jsonThe clank-preview-result/1 document includes the preview ID, normalized name, parent project, expiration, release digest, URL, and build/upload timing.
Remove a preview
Expiration removes the runtime and all platform-managed resources. Remove it sooner with:
clank preview remove feature-auth \
--confirm="delete-preview feature-auth" \
--acknowledge-data-lossThe acknowledgement is deliberate because preview databases can contain useful test data. A production project cannot be deleted while it still owns previews; remove or let them expire first.
Control-plane UI and API
The project's Previews page shows the active environment, URL, runtime status, current release, and expiration. Authorized members can remove a preview there. Creation remains a CLI-first operation so the exact local build and artifact digest are preserved.
The authenticated API is:
| Method | Endpoint | Purpose |
|---|---|---|
GET | /api/projects/:parentId/previews | List unexpired previews and the effective TTL/isolation policy |
POST | /api/projects/:parentId/previews | Create or refresh { "name": string, "ttlHours"?: integer } |
DELETE | /api/projects/:parentId/previews/:previewId | Permanently remove a preview after exact confirmation |
Creating, refreshing, and deleting previews requires deploy-capable workspace access and an account session or account CLI token. A project-scoped token cannot manage previews because it would not automatically gain authority over the newly isolated child project. Deploying a release to an existing preview uses the ordinary release API and authorization rules.
Isolation and limits
- Preview and production database paths live under different project IDs.
- Production secrets are not inherited. Set preview secrets explicitly if the app needs them.
- Migrations run against only the preview database.
- Realtime connections, MCP/OAuth endpoints, durable jobs, and logs belong to the preview URL.
- Preview projects are hidden from the top-level production project list and appear under their parent.
- Every preview counts toward both account and workspace project limits. This prevents previews from bypassing compute, port, storage, and retention limits.
- Nested previews are rejected.
- Names are unique within one parent project. The public hostname also carries a random project-ID suffix, so deleting and recreating a name does not accidentally address an older environment.
Self-hosting policy
Programmatic control planes can tune preview retention:
const platform = await openPlatform({
// ...
previews: {
defaultTtlMs: 3 * 24 * 60 * 60_000,
maxTtlMs: 14 * 24 * 60 * 60_000,
cleanupIntervalMs: 60_000,
},
});Cleanup runs at startup before application recovery and then in bounded background batches. Expired previews are not restarted. Deletion uses the same path containment, encrypted-backup removal, remote-artifact cleanup, token revocation, process shutdown, and audit path as an explicit project deletion. Set cleanupIntervalMs: false only when an external operator owns expiration.
CI naming
Use stable, low-cardinality names such as pull-482 or branch-auth-refresh. Always run the remove command when a pull request closes; TTL cleanup is the safety net for interrupted workflows. Do not put secrets, email addresses, commit messages, or untrusted free-form text in a preview name.