Core concepts
The five nouns you'll see everywhere in PreviewDrop, and how they fit together.
Workspace
A workspace is your team's container. Projects, team members, API tokens, billing, and environment variables all live inside it. Most teams only need one workspace. You can switch workspaces from the dashboard header if you belong to more than one.
Project
A project is a one-to-one binding between a Git repository and PreviewDrop. It holds the build config (Dockerfile path, exposed port, root directory), the default environment variables, and the access controls (who on the team can redeploy, who can delete). Every deployment belongs to exactly one project.
Deployment
A deployment is one attempt to build and run a specific Git commit. Each deployment moves through a finite set of states:
| State | Meaning |
|---|---|
building | Container image is being built. Build logs stream in Logs tab. |
deploying | Image built; waiting for the container health check to pass. |
ready | Healthy and reachable at the preview URL. |
failed | Build or container health check failed. See failureReason for the category. |
stopped | Deleted manually or hit TTL; URL no longer resolves. |
expired | Idle past the plan's TTL; container torn down, row retained for history. |
Terminal states (ready, failed, stopped, expired) are final — the pipeline never walks a deployment backwards. If you push again on the same branch, you get a new deployment, not a mutated old one.
Branch mapping
PreviewDrop automatically picks up every push to every branch on a connected repo. Each branch gets its own stable subdomain, so the URL stays the same across pushes — share it once with a reviewer and they'll always see the latest commit.
- New branch pushed → new deployment, new subdomain.
- New commit on an existing branch → new deployment, same subdomain; the old container is replaced on health.
- Branch deleted on Git → the preview is scheduled for teardown.
- PR merged → same as branch deleted (the source branch is usually removed).
TTL and expiry
Every preview has a time-to-live. If nobody visits it for the TTL window, the container is stopped to save resources — the row stays in your history so you can see what happened. A single click (or a redeploy) rebuilds the same commit.
| Plan | Preview lifetime |
|---|---|
| Free | 1 hour |
| Starter | 4 hours |
| Pro | 8 hours |
| Enterprise | 7 days |
See Pricing for the full limit matrix.
The pipeline, step by step
From Git push to live preview, here's what happens:
- Webhook received. GitHub/GitLab/Bitbucket posts a push or PR event to
/api/webhooks/<provider>. Signature is verified; unrelated events are dropped. - Deployment row created. PreviewDrop writes a
buildingrow and broadcasts a realtime event so the dashboard reacts immediately. - Repo cloned. The worker fetches the exact commit SHA into an isolated build directory.
- Image built. If a
Dockerfileexists, it's used. Otherwise PreviewDrop auto-detects the stack and builds one for you. Build logs stream to the dashboard. - Container started. The image runs with your env vars injected and the
PORTvariable set. Health checks poll until the app answers. - Routed. Once healthy, traffic is routed to the new container at the branch subdomain and the row flips to
ready. - Idle-reaped. A background job checks access logs every 5 minutes and stops containers that have gone quiet past their TTL.
What PreviewDrop is not
- Not production hosting. Previews are ephemeral by design. Use Railway, Fly, or your cloud of choice for prod.
- Not a CI runner. It builds and runs previews, but it doesn't replace your test suite. Most teams keep GitHub Actions for tests and use PreviewDrop for the URL.
- Not a database host. Your preview usually points at a shared dev/staging DB via env vars. See Environment variables.