.preview.yaml Reference
The .preview.yaml file at the root of your repository tells Previewkit how to build and deploy your stack for each pull request. This page documents every field.
Top-level shape
version: 1 # required, must be 1domain: string? # optional, override preview hostname suffixregistry: string? # optional, override image registry
apps: [App] # required, at least oneservices: [Service] # optionalhooks: post_deploy: [Hook] # optional| Field | Type | Default | Notes |
|---|---|---|---|
version | 1 | required | Schema version. Only 1 is supported today. |
domain | string | preview.autonoma.app | Overrides the hostname suffix. Wildcard DNS must be configured by the operator. |
registry | string | platform default | Container registry to push built images to. Usually leave unset. |
apps | list | required | One or more applications. Each gets a public HTTPS URL. |
services | list | [] | Backing services from the recipe catalog (databases, caches, etc.). |
hooks | object | {} | Lifecycle hooks. Today only post_deploy is supported. |
Apps
Each entry under apps becomes a Kubernetes Deployment plus a public HTTPS hostname.
apps: - name: api path: ./apps/api dockerfile: ./apps/api/Dockerfile # optional build_args: # optional NODE_VERSION: "20" port: 4000 env: DATABASE_URL: "postgresql://preview:preview@{{db.host}}:5432/preview" command: "node dist/server.js" # optional, overrides image CMD health_check: /health # optional replicas: 1 resources: cpu: 500m memory: 512Mi| Field | Type | Default | Notes |
|---|---|---|---|
name | string | required | Kubernetes-style name (lowercase letters, digits, hyphens). Also the leftmost label of the hostname. |
path | string | "." | Path to the build context, relative to the repo root. |
dockerfile | string | autodetect | Path to a Dockerfile (relative to repo root). If omitted, Previewkit looks for Dockerfile inside path; if none is found, Railpack auto-detects the framework. |
build_args | map<string, string> | {} | Build-time --build-arg values. |
port | integer | required | The container port the app listens on. |
env | map<string, string> | {} | Runtime environment variables. Supports templating. |
command | string | image CMD | Optional shell command to override the image entrypoint. Wrapped in /bin/sh -c. |
health_check | string | none | HTTP path for both readiness and liveness probes. |
replicas | integer | 1 | Number of pod replicas. |
resources.cpu | string | "250m" | CPU request (no limit). |
resources.memory | string | "256Mi" | Memory request and limit. |
Resulting URL
For an app named web in PR #42 of acme-corp/storefront, the URL is:
https://web-pr-42-acme-corp-storefront.preview.autonoma.app(Repo slugs are sanitized to fit DNS-label limits — long owner/repo names are truncated.)
Services
Services come from a curated recipe catalog. You don’t write Kubernetes manifests — you pick a recipe and Previewkit handles everything (Deployment, Service, persistent volume, readiness probes).
services: - name: db recipe: postgres version: "16" env: POSTGRES_DB: app resources: cpu: 500m memory: 1Gi| Field | Type | Default | Notes |
|---|---|---|---|
name | string | required | Used by other apps to address this service ({{<name>.host}}). |
recipe | string | required | One of the recipes listed below. |
version | string | recipe default | Image tag for the underlying service. |
env | map<string, string> | {} | Extra environment variables for the service container. |
options | map | {} | Recipe-specific config. See each recipe below. |
resources | object | 250m / 256Mi | Same shape as app resources. |
Available recipes
| Recipe | Default version | Port | Notes |
|---|---|---|---|
postgres | 16-alpine | 5432 | Persistent volume attached. Connection: postgresql://preview:preview@{{name.host}}:5432/preview. |
redis | 7-alpine | 6379 | No persistence. Connection: redis://{{name.host}}:6379. |
valkey | 7-alpine | 6379 | Open-source Redis fork. Same connection shape. |
temporal | (recipe-default) | 7233 | Local Temporal cluster for workflow testing. |
api-gateway | 1.27-alpine | 80 | Nginx-based router that fans requests to multiple apps. Requires options.routes. |
api-gateway options
services: - name: gateway recipe: api-gateway options: client_max_body_size: 25m routes: - path: /api target: api strip_prefix: true - path: / target: webEach route has path (URL prefix to match), target (app or service name to forward to), strip_prefix (boolean), and rewrite (optional path rewrite).
Hooks
hooks: post_deploy: - app: api command: "npx prisma migrate deploy" - app: api command: "node scripts/seed.js"post_deploy runs after every app is deployed and at least one pod for the target app is Running. Each step is executed via the Kubernetes API exec subresource (no kubectl needed), wrapped in /bin/sh -c. Steps run sequentially; the first failure aborts the rest.
| Field | Type | Notes |
|---|---|---|
app | string | Name of an app declared in apps. The hook runs inside its pod. |
command | string | Shell command to execute. |
Environment templating
The env map on apps (and on services) supports two kinds of placeholders that resolve at deploy time:
Service references
{{<name>.host}} and {{<name>.port}} resolve to the in-namespace DNS name and port of another app or service.
apps: - name: web env: API_URL: "http://{{api.host}}:{{api.port}}"
- name: api env: DATABASE_URL: "postgresql://preview:preview@{{db.host}}:5432/preview" REDIS_URL: "redis://{{cache.host}}:{{cache.port}}"
services: - name: db recipe: postgres - name: cache recipe: redis{{name.host}} is always the bare service name (in-cluster DNS). {{name.port}} is the recipe’s known port for services, or the declared port for apps.
Unknown names raise a deploy error with the list of valid names.
Context variables
Three variables describe the current PR context:
| Variable | Value |
|---|---|
{{pr}} | PR number (e.g. 42) |
{{namespace}} | Kubernetes namespace (preview-<owner>-<repo>-pr-<N>) |
{{owner}} | Repo owner (e.g. acme-corp) |
apps: - name: api env: ENV_LABEL: "pr-{{pr}}-{{owner}}" S3_PREFIX: "previews/{{namespace}}/"Full example
version: 1
apps: - name: web path: ./apps/web port: 3000 env: API_URL: "http://{{api.host}}:{{api.port}}" DATABASE_URL: "postgresql://preview:preview@{{db.host}}:5432/preview" health_check: /health
- name: api path: ./apps/api dockerfile: ./apps/api/Dockerfile port: 4000 env: DATABASE_URL: "postgresql://preview:preview@{{db.host}}:5432/preview" REDIS_URL: "redis://{{cache.host}}:6379" ENV_LABEL: "pr-{{pr}}" health_check: /health resources: cpu: 500m memory: 512Mi
services: - name: db recipe: postgres version: "16"
- name: cache recipe: redis
hooks: post_deploy: - app: api command: "npx prisma migrate deploy"Validation tips
- Names must match
^[a-z0-9][a-z0-9-]*[a-z0-9]$(Kubernetes-compatible). - At least one
appis required. versionmust be exactly1.- Service references in
envmust match a name declared elsewhere in the same file. - Hostnames combine
<app>-pr-<N>-<repo-slug>and must stay under 63 characters — keep app names short.