Deployments & rollbacks
Immutable releases with zero-downtime promotion and one-click rollback.
Lifecycle
| Status | Meaning |
|---|---|
queued | Accepted; waiting for a build slot (per-plan concurrency). |
building | Cloning, installing, building the image or static output. |
deploying | Starting containers and waiting for health checks. |
ready | Serving traffic. The previous release is retired. |
failed | Something broke — the previous release keeps serving. See the diagnosis card. |
Triggers
- Push — commits to the production branch deploy automatically (GitHub App).
- Manual — the Deploy button, per app, any branch.
- Rollback — re-deploys any previous successful release's commit.
- Image projects — redeploy on demand from the registered image.
Environments, approvals and checks
Every project has three built-in environments (production, preview, development) and can add custom ones under Environments in the project. A custom environment tracks a branch pattern: an exact name (staging) or a glob (release/*, feat/**). A push to a matching branch deploys to that environment with the variables of its kind and any domain bound to it; without a bound domain a custom environment serves at <project>-<environment>.buildfyio.com.
- Protected environments — mark an environment protected and every deployment routed to it waits at
queueduntil a workspace admin clicks Approve on the deployment page; Reject cancels it with a reason. Both are audited. - Deployment checks — turn on Require passing checks in Settings → Workflow and production deployments wait for the commit's GitHub check runs and statuses. Passing checks start the build; a failing one fails the deployment as
Checks failed: …without touching the live release, and checks still pending after 20 minutes fail it the same way. Rollbacks are exempt. - Pull requests — each deployment reports a
buildfyio/<environment>commit status (queued → building → ready/failed) and a PR deploy keeps one comment per app on the pull request with the preview URL.
New-workspace limits
Hobby workspaces that are younger than 7 days and have no payment method or paid plan share a pool of free capacity with every other new workspace. While a workspace is in the pool:
| Limit | Value | When it applies |
|---|---|---|
| Live apps, all new workspaces together | 25 (platform-wide pool) | Starting an app that is not live yet |
| Live apps per new workspace | 3, inside the shared pool | Starting an app that is not live yet |
| Deploys per hour | 12 per workspace | Every deploy, including redeploys |
- Redeploying an app that is already live is never blocked by the pool: it replaces the running release and adds no capacity.
- Adding a payment method under Billing takes the workspace out of the pool at once. Hobby does not charge the card. Upgrading to a paid plan does the same, and the limits end on their own after 7 days.
- Hobby has a hard stop at 100 build minutes a month (deploy builds and CI jobs both count), with a warning at 80%. It is never billed per minute; paid plans are billed per minute past their allowance (see pricing).
- Sign-up with a disposable email address is refused.
- Proxy, VPN and traffic-relay images (Xray, V2Ray, sing-box, gost, Shadowsocks, Hysteria, Trojan and similar) are refused at deploy time, and a workspace found running one is suspended. See the acceptable use policy.
Logs
Build and deploy logs stream live in the dashboard and are kept per deployment. Runtime logs stream from the running containers on the deployment page.
Build Doctor
Every failed deploy is diagnosed automatically. Instead of a wall of logs, you get a card naming the root cause and the fix — a missing module, an incompatible Node version, an out-of-sync lockfile, a crashing start command — and whether the fault is in the code or the platform. Coverage is effectively total; anything unrecognized still surfaces the failing log tail.
Per-app lineage
In multi-app projects each app has its own deployment history: promoting or rolling back one app never affects the others.