---
title: "Templates and previews"
description: "Create a new service from a template in one plan, and get a preview environment for every pull request with only the apps it changes and its own copy of staging data."
url: https://frazer.ai/docs/previews
index: https://frazer.ai/docs/previews/llms.txt
tokens: 3434
---

> For agents: this page is indexed at https://frazer.ai/docs/previews/llms.txt, and every page at https://frazer.ai/llms.txt. Copy commands from this file exactly.

# Templates and previews

Templates and previews are the developer-facing layer on top of [environments](https://frazer.ai/docs/gitops). A **template** creates a new service in one plan: its repository, its folder in your environment repository, its database, hostname and checks. A **preview** is a short-lived environment for one pull request, with only the apps it changes and its own copy of the staging database, deleted when the pull request merges. Both run on your staging cluster, on your own servers or on the Frazer fleet.

Product overview: [Templates and previews](https://frazer.ai/previews). Previews for every workspace, stack, plan level, program and past moment, what a change affects, test plans at three depths, test runs and their results as evidence are on [Previews and tests](https://frazer.ai/docs/previews/tests).

## How it works

**Templates.** A template is the supported, opinionated way to start something new. Its parameters are a JSON Schema form, and its workload part is written in [Score](https://score.dev), so a template asks for a database or a hostname by type and Frazer resolves each one to its own resource:

```yaml title="score.yaml (resources)"
resources:
  db: { type: postgres }
  dns: { type: dns }
```

Running a template is one plan that lists every effect before anything happens. Frazer publishes a starter set (Go gRPC service, TypeScript web app, worker, cron job, Postgres-backed API) in a public project; your teams add their own from a Git repository and share them with other projects. A service remembers its template’s version and the answers it was created with, so a new template version can reach existing services as pull requests.

**Previews.** A preview policy on a staging environment says which pull requests get a preview, which apps deploy, where the data comes from, and when it all goes away. For each matching pull request, Frazer renders a GitOps Application from an ApplicationSet with the pull request generator. Frazer owns that ApplicationSet inside the environment’s fence, so a preview can never reach outside the environment’s repository and namespaces. The generator listens on the repository’s webhook, the image comes from the pull request’s own CI build, and the Application is deleted when the pull request stops matching.

-   **Template**: a project resource that creates a service and everything it needs, shared with other projects.
-   **Preview policy**: the rules for previews on one environment: trigger, apps, isolation, database, lifetime and hostname.
-   **Preview**: one pull request’s running copy, in its own namespace, with its URL, state and cost.
-   **Database copy**: a clone of the staging database from its last volume snapshot, an empty database, or one filled by a seed job.

### Preview policy fields

| Field | What it sets |
| --- | --- |
| `environment` | The staging environment the preview derives from. |
| `apps` | The apps to deploy for a pull request. Only the services the pull request changes deploy; the rest are shared from staging. |
| `trigger` | The `preview` label, every pull request, or pull requests opened by agents only. |
| `isolation` | `namespace` (default) or `vcluster`, for apps that need cluster-scoped kinds. |
| `database` | `empty`, a `seed` job, or `clone` from the last volume snapshot of the staging database. |
| `ttl` | Delete on merge or close, or at the TTL. |
| `sleepAfter` | Scale the preview to zero after it has been idle this long. |
| `hostname` | `pr-<n>-<app>-<project>.preview.frazer.run`, behind Frazer sign-in by default. |

## Create a service from a template

To create the source repository, a template uses the opt-in **Frazer** writer GitHub App, with permission to create repositories, which your organization turns on separately.

1.  Pick a template and see its plan.
    
    ### CLI
    
    ```sh
    frazer templates run go-grpc-service --name rates-api --project acme-staging --dry-run
    ```
    
    ```text title="Output"
      + repo        acme/rates-api (from template go-grpc-service@3)
      + git         platform-envs: apps/core/rates-api/ (staging commit, production PR)
      + database    rates-api-db (Postgres, 1 instance, 20 GiB)
      + hostname    rates-api.acme-staging.<apps-domain>, certificate
      + check       HTTPS /healthz every 60 s from 3 locations; 4 default alert policies
    ```
    
    The plan also shows what the new service costs per month.
    
    ### Console
    
    In your organization’s **Home**, open **Create**. Pick a template from the gallery and fill in its form. The plan card lists every effect and the monthly cost.
    
2.  Apply the plan: run the command again without `--dry-run`, or choose **Apply** on the plan card.
    
3.  Open the new repository. Its CI builds, signs and pushes the image, then writes the digest into `apps/core/rates-api/` in your environment repository: staging by commit, production by pull request.
    
4.  Find the service in the project’s **Engineering › Service catalog**, with its owner group, links, health and last deploys.
    

What running a template does, and how each effect is applied:

| Effect | Applied as |
| --- | --- |
| A source repository from a skeleton, with CI that builds, signs and writes the digest | The opt-in **Frazer** writer App |
| The app’s folder in the environment repository: staging by commit, production by pull request | Git |
| Database, hostname and certificate, uptime check, default alert policies | Frazer API resources |
| Catalog entry and owner group | Frazer API |
| A workspace template for devboxes and agents; optional reviewer and agent triggers | Frazer API |

No custom template code runs in Frazer’s control plane. A custom step is a container that runs in your organization’s own agent sandbox.

## Turn on previews for an environment

You need a connected staging [environment](https://frazer.ai/docs/gitops#connect-an-environment) whose apps’ CI pushes an image for each pull request.

1.  Create a preview policy on the staging environment.
    
    ### CLI
    
    ```sh
    frazer preview-policies create --environment staging --trigger label:preview
    ```
    
    ### Console
    
    Open **Engineering › Preview environments** and create a policy for the staging environment. The plan shows how each preview gets its data, including whether the cluster’s storage can take snapshots, before you turn the policy on.
    
    A policy on Acme’s staging environment reads like this:
    
    | Setting | Value |
    | --- | --- |
    | Environment | staging · `acme/platform-envs` `envs/staging` |
    | Trigger | label `preview` · every agent pull request |
    | Apps | only the apps the pull request changes; the rest shared from staging |
    | Isolation | namespace `pv-<number>` |
    | Database | clone of the nightly `orders-db` volume snapshot |
    | Hostname | `pr-<n>-<app>-acme-staging.preview.frazer.run` · Frazer sign-in |
    | Lifetime | deleted on merge or close · TTL 7 days |
    
2.  Add the `preview` label to a pull request in an app’s source repository.
    
3.  Wait for the pull request’s CI to push its image. The preview deploys the changed apps into their own namespace, clones the database and runs the pull request’s migrations against the copy.
    
4.  Open the preview from the pull request: Frazer posts its URL, state and running cost as a check. Or list previews:
    
    ```sh
    frazer previews list
    ```
    

Coding agents test their own changes against the same preview, and the [Reviewer](https://frazer.ai/docs/reviewer) links to it and runs its smoke checks there. People, agents and the Reviewer share one preview per pull request.

## Data in previews

By default a preview gets a copy of the **staging** database from its last volume snapshot. Migrations in the pull request run against the copy, so they cannot touch shared staging data, and the copy is deleted with the preview.

If the cluster’s storage cannot take snapshots, Frazer restores the copy from the object-store backup instead, which is slower. The policy’s plan says which path a preview takes.

> **Caution:**
> 
> A preview never copies production data by default. Cloning production needs an approval and a masking job.

## Manage previews

`frazer previews list` shows every live preview; `frazer previews open`, `extend` and `delete` act on one of them. In the console, **Engineering › Preview environments** lists live previews per pull request with their URL, age, cost and whether they are asleep; you can extend or delete each one. A preview is deleted when its pull request merges or closes, or at its TTL, even if nobody closes the pull request. With `sleepAfter` set, an idle preview scales to zero between visits.

## Previews for serverless stacks

A [serverless stack](https://frazer.ai/docs/serverless) gets previews from the same kind of policy, with `target: stack` instead of an environment. A pull request opens a preview stack: the service as a tagged revision in a preview namespace, a Postgres branch from a snapshot of the stack’s database, a fresh Valkey instance and a scratch bucket prefix. It is deleted when the pull request closes, or after 7 days.

## Access and audit

-   **Developer**: sets a preview policy on an environment that allows the `preview` permission profile.
-   **Frazer**: owns the ApplicationSet that makes previews, inside the environment’s fence.
-   **Approver**: approves a preview that clones production data; the clone runs with a masking job.
-   **Template author**: publishes a template in a project and shares it with other projects.

Frazer logs every preview with its pull request, image digest and database copy; every template run as one plan with each effect; and every extend and delete.

## Limits and quotas

| Setting | Default |
| --- | --- |
| Preview lifetime | Deleted on merge or close, or at the TTL: 7 days |
| CPU overcommit | Up to 4:1 for previews; memory is never overcommitted |
| Quota | Previews count against the project’s quota |
| Data source | Staging; production needs an approval and a masking job |
| Hostname | Behind Frazer sign-in |

## Pricing

Previews run on your staging cluster’s capacity. On your own servers they are part of the per-core server fee; on the Frazer fleet they bill at the fleet compute rates. Each preview’s running cost is on its pull request and has its own line in billing. What a template creates bills as itself, and the plan shows the monthly cost first.

| Templates and previews | On your servers | On the Frazer fleet |
| --- | --- | --- |
| Price | No preview fee · runs on your cores | No preview fee · fleet rates per second while it runs |

Every line, with the estimator: [pricing](https://frazer.ai/pricing#lines).

## Troubleshooting

| Symptom | Cause | Fix |
| --- | --- | --- |
| A pull request gets no preview | It does not match the policy’s trigger, such as a missing `preview` label. | Add the label, or change the policy’s trigger. |
| The preview stays in **Building**, waiting for the image | The pull request’s CI has not pushed its image yet. | Check the pull request’s CI run; the preview deploys when the image arrives in Frazer Registry. |
| The preview **Failed** on a migration | A migration in the pull request failed against the database copy. | Read the job logs from the preview, fix the migration and push; staging data was never touched. |
| The database copy is slow | The cluster’s storage cannot take snapshots, so the copy is restored from the backup. | Expected on that storage class; the policy’s plan says which path applies. |
| The preview URL asks for a sign-in | Previews sit behind Frazer sign-in by default. | Sign in with an account that may see the project. |
| A preview is gone before review finished | It reached its TTL. | Extend the next one with `frazer previews extend`, or raise the policy’s TTL. |
| A template plan cannot create the repository | The **Frazer** writer App is not installed, or creating repositories is not allowed for your organization. | Install the App and turn on repository creation, or create the repository yourself and re-run. |

## Reference

### CLI

| Command | What it does |
| --- | --- |
| `frazer templates run` | Run a template; with --dry-run, print one plan with every effect (repository, environment folder, database, hostname, checks) before anything happens. |
| `frazer preview-policies create` | Create a preview policy on an environment, with the trigger that decides which pull requests get a preview. |
| `frazer previews list` | List live previews with their pull request, URL, state, age and cost. |
| `frazer previews open` | Open a preview's URL. |
| `frazer previews extend` | Keep a preview past its TTL. |
| `frazer previews delete` | Delete a preview and its database copy. |

All of them: [CLI reference](https://frazer.ai/docs/cli).

### MCP tools

| Tool | What it does |
| --- | --- |
| `previews` | Read previews and preview policies, so agents see the same previews as people. |

All of them: [MCP tools reference](https://frazer.ai/docs/mcp).

## Related

-   [Environments and GitOps](https://frazer.ai/docs/gitops): the environments previews derive from.
-   [Reviewer](https://frazer.ai/docs/reviewer): reviews that run against a preview.
-   [Serverless](https://frazer.ai/docs/serverless): stacks with preview stacks per pull request.
-   [Databases](https://frazer.ai/docs/databases): the Postgres behind database copies.
-   [Templates and previews product page](https://frazer.ai/previews)

## Pages in Templates and previews

- [Overview](https://frazer.ai/docs/previews.md) (this page)
- [Frazer QA](https://frazer.ai/docs/previews/tests.md)
