Deploy a preview environment for every pull request: a practical guide
Giving every pull request its own preview URL is one of those workflow changes that looks small on paper and completely reshapes how a team ships. Reviewers stop squinting at diffs and start clicking through working software. Designers see real behaviour on real data. Product managers approve features from a link instead of waiting for a demo.
This guide is a practical checklist for setting this up for your team — what matters, what to skip, and the places it typically goes wrong.
What you actually need
- A containerised application. One
Dockerfilethat builds and starts your app is enough. No framework lock-in required. - A way to provision a database per branch. This is what separates a toy preview from a useful one.
- A URL routing layer that maps
{branch}-{project}.yourhostto the right container. - A teardown trigger when the PR closes or the branch is deleted.
- A way to pause environments so they do not bill when nobody is using them.
What to skip on day one
- Per-region previews. Previews do not need to be global; they need to exist.
- Complicated authentication on the preview URL. A simple basic-auth or a shareable token is enough for most teams.
- Environment-specific feature flags. Your flag system probably already handles this.
- Seeding from production. Start with an empty DB or a lightweight fixture; add realistic seeding later.
Where it usually goes wrong
Three classic failure modes we see again and again:
- Cost runs away. Teams stand up preview environments, forget to tear them down, and discover a $2,000 AWS bill at end of month. Fix: automatic teardown on branch delete, plus per-second billing so an idle preview is a rounding error, not a line item.
- Database drift. Preview environments end up on a different schema than production because migrations never ran. Fix: always run migrations as part of the deploy; treat the preview database the same way you treat prod schema-wise.
- Secrets sprawl. Environment variables get duplicated per preview and drift. Fix: store secrets at the project level, inject them into every environment, rotate in one place.
Using Nexos as the preview layer
Nexos gives you all five of the essentials above with zero scripting. Connect a GitHub repo, every branch automatically provisions a preview environment with its own app container and database. The URL is deterministic, the teardown is automatic, and you can pause any environment to stop billing with one click.
Most teams get this working for a real app in under an hour — the longest part is usually figuring out the one environment variable they forgot to add.