Skip to content

Preview environments

Every pull request can get its own running copy of your service, on its own URL, rebuilt on every push and removed when the pull request closes.

How previews work

When a pull request is opened against a repository a service deploys from, HostStack builds the pull request's branch and runs it as a preview next to the service's live deploy. The live deploy is not touched: the preview gets its own container and its own hostname.

There is no separate switch for previews. On GitHub they follow the service's auto-deploy setting; on GitLab, Bitbucket and Codeberg every service linked to the repository gets them. Each new push to the pull request replaces the preview with a fresh build.

What starts and stops a preview

ProviderCreates or rebuildsRemovesWhich services
GitHubPull request opened, reopened or pushed toClosed or mergedServices with auto-deploy turned on
GitLabMerge request opened or updatedClosed or mergedEvery service linked to the repository
BitbucketPull request created or updatedMerged or declinedEvery service linked to the repository
CodebergPull request opened, reopened or pushed toClosed or mergedEvery service linked to the repository

A preview is created for a pull request into any branch, not only the branch the service deploys. Draft pull requests and pull requests from forks are treated like any other. On GitLab, reopening a merge request does not bring its preview back; push a commit to it instead.

The preview URL

Each preview is served on a hostname built from the pull request number and the service's slug:

pr-<number>-<service-slug>.preview.hoststack.dev

Pull request 42 of a service with the slug web is at pr-42-web.preview.hoststack.dev. The hostname stays the same across pushes to the same pull request. Previews are always served with noindex, so search engines leave them out.

On GitHub, the HostStack app comments on the pull request each time a preview goes live:

### Preview Environment Ready

| | |
|---|---|
| **URL** | [pr-42-web.preview.hoststack.dev](https://pr-42-web.preview.hoststack.dev) |
| **Commit** | `1a2b3c4` |
| **Built** | in 48s |

_This preview will be automatically destroyed when the PR is closed._

A push posts a new comment rather than editing the old one. GitLab, Bitbucket and Codeberg get no comment; find the URL on the service's Previews tab.

What a preview shares with the service

A preview is a deploy of the same service from another branch, so it runs with the service's own configuration:

  • the same environment variables and env groups, secrets included;
  • the same linked databases and other resources — the production ones;
  • the same size, build settings, start command and pre-deploy command.

There is no preview-only configuration and no variable that tells the app it is running as a preview.

Cleanup

  • Closing or merging the pull request (declining it, on Bitbucket) stops and removes the preview.
  • As a backstop, a preview is removed 7 days after it was built. An hourly job does the sweeping, and each push starts a new 7 days.
  • You can remove a preview yourself from the Previews tab with its delete button, or through the API below. The pull request is not affected.
  • A preview runs at the service's size, next to the live deploy, until it is removed — close pull requests you're done with rather than leaving them to the 7-day sweep.

Manage previews

The service's Previews tab lists Active Previews and Destroyed Previews. Deploy Preview starts one by hand from a PR number, a title and a branch — useful for a provider that doesn't send webhooks, or from CI.

Previews are not in the CLI, SDK or MCP server yet; use the REST API with an API key:

# List (includes destroyed previews)
curl -H "Authorization: Bearer $HOSTSTACK_API_KEY" \
  https://hoststack.dev/api/previews/$TEAM_ID/svc_.../previews

# Create or rebuild the preview for PR 42
curl -X POST -H "Authorization: Bearer $HOSTSTACK_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"prNumber": 42, "prTitle": "Add search", "branch": "feature/search"}' \
  https://hoststack.dev/api/previews/$TEAM_ID/svc_.../previews

# Remove one
curl -X DELETE -H "Authorization: Bearer $HOSTSTACK_API_KEY" \
  https://hoststack.dev/api/previews/$TEAM_ID/svc_.../previews/<preview-id>

$TEAM_ID is the Team ID printed by hoststack whoami. Creating and removing previews needs the member role, and each is limited to 30 requests a minute.

Next steps

Essential cookies only — for login sessions. No tracking. Details