Preview Environments & Promote to Production
A live, isolated environment for every pull request or branch, and a one-click way to ship staging's exact commit to production.
Beyond the single production deploy every app starts with, DeployOS can spin up temporary, fully isolated copies of an app — one per open pull request, or one per branch — and, separately, pair a staging app with a production app so promoting a build is a single click instead of a redeploy.
Both live in an app's Config tab, under Environments & pipelines.
PR preview environments
Turn on Enable PR preview environments and set a Preview base domain (e.g. preview.myapp.com). From then on:
- Every open pull request against the app's repo gets its own deployment at
pr-<number>.<preview base domain>— PR #42 lands atpr-42.preview.myapp.com. - DeployOS posts a comment on the PR itself with the live preview URL once it's up (or the error, if the build failed).
- Pushing new commits to the PR redeploys the same preview in place.
- Closing or merging the PR automatically tears the preview down (containers, volumes, images, and its route — same full cleanup as removing a regular app).
- Up to 3 open previews per app at a time — the 4th open PR gets a comment asking you to close one first, rather than silently failing.
- If the parent app has a Postgres database, each preview gets its own schema (not a full separate database) so previews can't stomp on each other's data or production's. This is best-effort: if schema creation fails for any reason, the preview still deploys, just sharing the parent's schema, with a warning in the PR comment.
Branch preview environments
Turn on Enable per-branch preview environments (same Preview base domain field, shared with PR previews). Instead of watching pull requests, this watches every branch in the repo:
- A push to a branch called
feature-xdeploys tofeature-x.<preview base domain>. - Every subsequent push updates that same preview.
- Deleting the branch tears the preview down.
- There's no picking-and-choosing which branches get one — every branch with a new commit gets a preview as long as the toggle is on and there's room under the 3-open-previews cap. If your repo has a lot of long-lived branches, be mindful of that before turning this on.
DNS: the one manual step
DeployOS auto-creates the route (Traefik/Caddy config + Let's Encrypt certificate) for every preview subdomain the moment it deploys — that part needs nothing from you. What it doesn't do is touch DNS: DeployOS has no DNS-provider integration, so a brand-new subdomain like pr-42.preview.myapp.com won't resolve unless something already points it at your server.
The fix is a one-time wildcard DNS record: *.preview.myapp.com → your server's IP, set up once at whatever registrar or DNS host you use. Once that's in place, every past and future preview subdomain resolves automatically — you never add a DNS record per PR or per branch.
Both watchers need the app open
Same tradeoff as auto-deploy on push: DeployOS is a desktop app, not a server GitHub can send webhooks to, so PR and branch previews are polled (every ~10 seconds) rather than pushed. If DeployOS is closed when you open a PR or push a branch, the preview appears the next time you open the app and it sweeps.
Promote to production
A separate, simpler pipeline for a common case: you have a staging app you deploy to freely, and a production app you want to update deliberately, on your own schedule, with exactly what staging is currently running — not "redeploy from latest and hope."
- On the staging app's Config tab, set Promotes to to the production app.
- Deploy staging normally until it's in the state you want to ship.
- On staging's Overview tab, click Promote to
<production app>.
DeployOS checks out that exact commit — the one staging currently has live — and rebuilds it on the production app, from source, at that pinned commit. It's not a copy of a cached image, so this works even if staging and production live on different servers with different builders. The production app needs to already exist and be configured (repo, domain, etc.) the normal way; promoting only ever changes which commit it's running.
Promote is disabled until staging has deployed at least once — there's nothing to promote before that.
Next: Deployment History & Rollbacks for the mechanism promote is built on, or Auto-Deploy on Push for the always-on production case.