# How to Set Up Preview Deployments for Pull Requests
The single biggest upgrade to a code review workflow is being able to *click a link* and use the change, not just read the diff. That's what preview deployments give you: every pull request gets its own live, isolated environment. Here's how to set them up and the gotchas to plan for.
What a preview deployment actually is
When you open a PR, the platform builds that branch and deploys it to a fresh, temporary environment with its own URL — something like pr-142-myapp.previews.example.com. Reviewers, designers, and PMs can test the real running change. When the PR merges or closes, the environment is torn down.
The benefits compound:
- Reviewers test behavior, not just code.
- Designers and non-engineers can sign off without a local setup.
- Bugs are caught in a production-like environment before merge.
- QA happens per-change instead of in a shared, contended staging environment.
How it works under the hood
The typical mechanism:
- 1A webhook fires when a PR is opened or updated.
- 2The platform builds the PR's branch (the same build pipeline as production).
- 3It deploys to an isolated environment with a unique URL.
- 4A bot comments the preview URL on the PR.
- 5On merge/close, the environment is destroyed and resources reclaimed.
Challenge 1: Databases in ephemeral environments
The hardest part of previews is data. Your preview app needs a database, but you do *not* want it touching production data. Options, roughly in order of safety:
| Strategy | Isolation | Cost / effort |
|---|---|---|
| Fresh ephemeral DB per PR, seeded | Highest | More resources |
| Shared preview DB (separate from prod) | Medium | Cheaper, risk of cross-PR collisions |
| Read-only replica of anonymized data | High | Setup-heavy |
| Point at production | None — don't | Dangerous |
For most teams, a fresh database seeded with fixtures or a small anonymized dataset is the right default. Never let preview environments write to production.
Challenge 2: Secrets and external services
Previews need API keys, but giving an ephemeral, easily-spun-up environment your live Stripe key is asking for trouble. Use *test-mode* or sandbox credentials for previews:
# Production
STRIPE_SECRET_KEY=sk_live_...
# Preview environments
STRIPE_SECRET_KEY=sk_test_...Third-party webhooks (payments, OAuth callbacks) need URLs that change per preview. Either configure them to accept the preview URL pattern or stub them in preview mode.
Challenge 3: Cost and cleanup
Ephemeral environments that never get cleaned up become a quiet cost leak and a security surface. The cleanup-on-close step is not optional. If you build previews yourself, ensure your teardown runs even when a PR is force-closed or abandoned. Scale-to-zero helps a lot here — an idle preview that scales to zero costs nothing while still being reachable on demand.
Setting up previews with PandaStack
PandaStack is built around Git-driven deploys, and its instant-preview environment at [pandastack.ai](https://pandastack.ai) is designed for exactly this fast feedback loop. Because deployments are triggered from your connected Git repo and each app builds through the same pipeline (rootless BuildKit in ephemeral Kubernetes Job pods → image in Artifact Registry → Helm deploy), branch builds get the same treatment as production builds, with live build logs so reviewers can see what happened.
For isolation, the patterns above still apply: use a separate preview database (PandaStack's managed databases make spinning one up straightforward, with DATABASE_URL auto-injected) and test-mode secrets via per-app environment variables. Free-tier apps use scale-to-zero on preemptible nodes, which is well suited to preview environments that sit idle between review sessions — just be aware they cold-start after inactivity.
A clean preview workflow
Open PR
│
▼
Build branch ──► Deploy isolated env ──► Bot comments URL
│ │
│ ▼
│ Reviewers test live app
▼
Merge/close ──► Tear down environmentBest practices checklist
- ✅ Every preview is fully isolated from production data
- ✅ Use test/sandbox keys for third-party services
- ✅ Seed preview databases with safe fixtures
- ✅ Post the preview URL automatically on the PR
- ✅ Guarantee teardown on merge/close
- ✅ Use scale-to-zero to keep idle preview cost near zero
References
- [GitHub: About pull request webhooks](https://docs.github.com/en/webhooks/webhook-events-and-payloads#pull_request)
- [Stripe: Test mode keys](https://docs.stripe.com/keys)
- [The Twelve-Factor App: Dev/prod parity](https://12factor.net/dev-prod-parity)
- [GitHub deployments API](https://docs.github.com/en/rest/deployments/deployments)
Get fast preview feedback on every change — try PandaStack's instant previews and free tier at [dashboard.pandastack.io](https://dashboard.pandastack.io).