Skip to main content

Preview Environments

Live preview URLs for every PR, automatically spun up and torn down.

Text Guide

Preview Environments

FlightDesk spins up an isolated Docker container for every PR so reviewers can test changes in a real running environment without pulling the branch locally. When the PR closes, the container is torn down automatically.

How It Works

  1. A PR is opened on a connected repository
  2. FlightDesk receives the GitHub webhook
  3. A Docker container is created on a worker server, the repo is cloned, and your setup commands run
  4. Your configured processes start inside the container
  5. A unique HTTPS URL is assigned based on the branch name, e.g. fix-auth.preview.flightdesk.dev
  6. The task status moves to Preview Ready and the URL appears on the task detail page
  7. On every subsequent push to the branch, FlightDesk pulls the latest code and restarts the processes
  8. When the PR closes, the container is torn down and compute stops billing

Enabling Previews

Preview environments are opt-in per project. Enable them in Project Settings → Preview.

Setup Commands

Commands that run once inside the container before your processes start. Use these to install dependencies, run builds, generate Prisma clients, etc.

pnpm install
pnpm build:libs
pnpm prisma generate

Commands run in sequence. If any command fails, the preview is marked as errored and logs are available on the task page.

Processes

Each process defines something to run and the port it listens on. Configure them as a JSON array in project settings:

[
  { "name": "api", "command": "pnpm nx serve api", "port": 3333 },
  { "name": "web", "command": "pnpm nx serve web", "port": 4200, "primary": true }
]

Fields:

  • name — identifier used in URLs and logs
  • command — shell command to start the process
  • port — the port the process listens on inside the container
  • primary — marks the main process; its URL gets the clean subdomain (no process name prefix)

URL pattern with branch fix-auth and the above config:

  • Web (primary): https://fix-auth.preview.flightdesk.dev
  • API: https://api-fix-auth.preview.flightdesk.dev

Environment Variables

Store your project's env vars as encrypted secrets in Project Settings → Secrets. They are decrypted and injected into the container at spin-up time.

FlightDesk only auto-injects NODE_ENV, NODE_OPTIONS, and NX_DAEMON. Everything else your app needs must be set as a secret — including HOST=0.0.0.0 (and VITE_HOST=0.0.0.0 for Vite), without which processes bind to localhost and the proxy returns 502s.

Use dynamic template variables so URLs automatically match the preview:

SITE_URL         = {{PREVIEW_URL}}
API_URL          = {{PREVIEW_URL:api}}
VITE_API_URL     = {{PREVIEW_URL:api}}
CORS_ORIGIN      = {{PREVIEW_URL:web}}

See Preview Environment Variables for a full reference.

Framework Guides

For step-by-step setup instructions specific to your stack:

Idle Timeout

Previews automatically suspend after a configurable period of inactivity (default: 4 hours). A suspended preview pauses its Docker container, stopping compute billing. It resumes automatically when someone visits the preview URL.

SSH Access

Every preview container includes SSH access for debugging. Add your public SSH key at Settings → Personal → Security, then connect:

ssh flightdesk@fix-auth.preview.flightdesk.dev

Or use the CLI shortcut:

flightdesk ssh <task-id>

Manual Controls

On the task detail page you can:

  • Spin up — manually start a preview for a task (useful if auto-spin-up was skipped)
  • Restart — re-run processes without re-cloning the repo (fastest way to pick up a config change)
  • Tear down — stop the preview early and free the compute

Pricing

| State | Cost | |---|---| | Running | $0.02 / hour | | Suspended | $0.001 / hour | | Torn down | $0 |

Every subscription includes $5 of monthly compute credits, roughly 250 running hours.

Troubleshooting

Preview is stuck on "Starting"

Open the task page and click View Logs. Common causes:

  • A setup command failed — check for missing dependencies or a build error in the logs
  • The process exited immediately after starting — usually a config error or crash on startup
  • The health check timed out — if your app takes longer than 5 minutes to start, the preview may be marked ready anyway once the timeout passes

Preview isn't updating after a push

Pushes trigger an update within about 30 seconds. If nothing happens:

  • Check that GitHub webhooks are being delivered (Settings → Organization → Integrations → GitHub)
  • Confirm the push is to the same branch as the open PR

A secret isn't taking effect

Secrets are injected at spin-up time. Adding or changing a secret after the preview is running requires a Restart from the task page to take effect.