# How to set up preview environments for every pull request

> A step-by-step guide to giving every branch its own live, TLS-secured environment on Ownkube, plus what's manual today versus what native per-PR previews will automate.

- **Published:** 2026-09-06
- **Author:** Ownkube team
- **Category:** How-To
- **Tags:** preview-environments, pull-requests, ci-cd, tutorial, ownkube-compute
- **Canonical URL:** https://ownkube.io/blog/preview-environments-per-pr
- **Cover:** https://ownkube.io/blog/preview-environments-per-pr.png

---
A preview environment is a live, disposable copy of your app that runs the code on a branch instead of main, so a reviewer or a designer can click around a pull request instead of reading a diff. Ownkube does not yet spin one up automatically the moment you open a PR (that automation is on the roadmap), but the pieces it does ship, a deployment per branch, an environment per stage, and a public hostname with automatic TLS [in under a minute](/blog/deploy-a-web-app-in-under-a-minute), get you a working preview today with a few clicks instead of a platform team.

This guide covers what's shipped, how to set up a per-branch preview environment on Ownkube Compute, and how to tear it down cleanly when the branch merges.

**TL;DR**

- Ownkube doesn't auto-create or auto-delete a preview environment when a pull request opens or closes yet. That's listed on the roadmap as native per-PR isolation with auto-teardown.
- What is shipped: an **environment** per stage or branch, a **deployment** that builds from a specific branch on git push, and an auto-allocated `*.ownkube.app` hostname with automatic TLS for every deployment.
- You create the branch's environment and deployment once, from the dashboard, and Ownkube rebuilds it automatically on every push to that branch after that.
- **Health checks** on the deployment's Settings tab keep the preview's URL from serving traffic until the container actually passes its readiness probe, so reviewers never hit a half-started app.
- Delete the environment when the PR merges or closes. Environment-level shared variables aren't available yet, so set variables per deployment, not once per environment.

## What "preview environment" means on Ownkube today

Ask for "preview environments" and most people mean one specific thing: open a pull request, get a URL automatically; close it, and the URL and its resources disappear automatically. That exact loop, triggered by the pull request lifecycle itself, isn't wired up on Ownkube yet. It's real work on the roadmap (per-PR isolation with auto-teardown), and we'd rather tell you that plainly than have you go looking for a webhook setting that doesn't exist.

What is wired up, and generally available today, is the building block underneath that loop: an **environment** for each stage of your app, and a **deployment** inside it that rebuilds every time you push to a chosen branch. Multi-environment promotion lets you move a build from one environment to the next once it's reviewed. Put those together and a "preview environment" is a couple of dashboard clicks: a new environment named after the branch, a deployment pointed at that branch, and a live `*.ownkube.app` URL with TLS already on it. It isn't automatic yet, but it's fast, and it's real infrastructure, not a shared staging box everyone fights over.

## What you need before you start

- A GitHub or GitLab repository connected to your Ownkube organization (GitHub App install, or a GitLab account connection).
- A repository that either has a [Dockerfile](https://docs.docker.com/) or is in a language Ownkube's automatic build can detect (most common Node, Python, Go, and Ruby setups build with no Dockerfile at all).
- The branch you want to preview, already pushed.

## Step 1: create an environment for the branch

Environments are how Ownkube groups deployments into a stage: production, staging, and now, a branch preview. From your organization's dashboard, open **Settings**, go to the **Environments** tab, and create a new one named after the branch (`preview-checkout-redesign` reads better six weeks from now than `env-3`).

You don't need a naming convention Ownkube enforces, but a consistent one saves you from guessing which environment belongs to which stale PR when you're cleaning up later.

## Step 2: point a deployment at the branch

Inside the new environment, create a deployment from your connected repository, and pick the branch instead of the default one.

```text
Deploy new -> Web service
Source: your-org/your-repo
Branch: checkout-redesign
Build target: Dockerfile detected (or Auto, if the repo has none)
Environment: preview-checkout-redesign
```

If the repo has a Dockerfile, Ownkube builds from it (and lets you pick which one if there's more than one). If it doesn't, Ownkube detects the language and builds automatically, no Dockerfile required either way.

Set the port your app listens on and any environment variables the branch needs. Variables are per-deployment today, there's no environment-level shared variable set yet, so if the preview needs the same secrets as staging, copy them over once when you create the deployment.

## Step 3: confirm the health check before you share the link

Every deployment has a [**Health checks**](/docs) section on its Settings tab (startup, liveness, and readiness probes). Point it at a real endpoint your app already exposes, `/health` or `/` is fine for most services, so Ownkube knows the container is actually ready before it lets traffic hit the public URL.

```text
Health check path: /healthz
Initial delay: 5s
Timeout: 3s
```

Skip this and the auto-allocated hostname can resolve before your app has finished starting, which is exactly the kind of flaky first impression a preview environment is supposed to avoid.

## Step 4: share the URL

Once the deployment's status reads healthy, its **Overview** tab shows the public hostname, an auto-allocated `*.ownkube.app` domain with automatic TLS already issued. Drop that link in the pull request description or a comment. Every subsequent push to the branch rebuilds the same deployment and the URL doesn't change, so you only need to post it once per PR.

```bash
# Verify a preview deployment is live and healthy from the CLI
okctl deploy status <deployment-id> -o json
```

## Step 5: tear the environment down when the PR closes

This is the manual half, today. When the branch merges or the PR closes, delete the deployment (or the whole environment, if you made one per branch) from the dashboard. Nothing sensitive is left running: a deleted deployment stops billing and releases its hostname immediately.

Until native auto-teardown ships, the honest answer is to treat this the way you'd treat closing a stale browser tab: a habit, not automation. If your team opens a lot of pull requests, keeping preview environment names prefixed and sorted makes the monthly cleanup pass fast.

## When to just use staging instead

Not every branch needs its own environment. A one-line copy fix doesn't need a full preview; a checkout flow rewrite does. If your team finds itself creating a preview for nearly every PR, that's also a signal you're a good candidate to hear about native per-PR previews first once they ship, keep an eye on the [changelog](https://ownkube.io/changelog).

For teams that outgrow a single shared staging environment before automated previews land, our [internal developer platform guide](/blog/internal-developer-platform-2026) covers the broader pattern of self-service environments without a platform team building it from scratch.

## FAQ

### Does Ownkube create a preview environment automatically when I open a pull request?

Not yet. That's on the roadmap as native per-PR isolation with automatic teardown. Today you create the environment and deployment once, and Ownkube rebuilds it automatically on every push to the branch after that.

### Does a preview environment get its own URL and TLS certificate?

Yes. Every deployment, including one on a branch, gets an auto-allocated `*.ownkube.app` hostname with automatic TLS. That part is fully automatic; only the create-and-delete step around it is manual today.

### Can I set an environment variable once and have every preview inherit it?

Not yet. Environment-level shared variables exist in the data model but there's no UI to set them, so variables are per-deployment. Copy what a preview needs when you create it.

### What happens to a preview environment's data when I delete it?

Deleting the deployment removes it and releases its hostname. If the preview included its own database or cache, that data goes with it, so don't point a branch preview at production data.

### Is there a cost to running a preview environment?

Yes, a preview deployment draws down your [prepaid wallet](/blog/prepaid-wallet-no-surprise-bill) like any other deployment, metered per minute by default so an idle preview between review rounds barely registers. Delete it once the PR is done rather than letting it run indefinitely.

## Where Ownkube fits

If you want the exact "PR opens, URL appears, PR closes, it's gone" loop, that's a roadmap item, not something to fake here. What you can build today is close: a real environment and a real deployment per branch, live in about a minute, with a working TLS URL and a health check protecting it, torn down with one click when you're done. For a team that's tired of a single shared staging box, that's a meaningful upgrade even before the last mile automates. [Deploy your first app](https://app.ownkube.io/login).