Deployments
A deployment is one attempt to build (or reuse) an image and run it behind your app’s URL.
Triggers
- GitHub webhook — pushes to the tracked branch (HMAC-validated), when auto-deploy is enabled
- Manual — the Deploy button in the UI
- Rollback — redeploys a previous deployment
Status machine
Every deployment moves through:
cancelled (not shown), and one stuck in a non-terminal state for over 15
minutes is failed at startup with a clear reason.queued building live superseded failed cancelled
Exactly one deployment per app is live — the one currently serving
traffic. When a new deployment goes live, the previous one is demoted to
superseded. Superseded deployments keep their image and remain valid
rollback targets.
Logs
Build and deploy logs stream live over SSE and are persisted per deployment, so you can inspect a failed deploy after the fact. The five most recent deployments per app are retained; older rows, log files, and images are reclaimed.
For the running app’s own output, see the app’s Logs tab — Metrics & Logs.
Safety properties
- Builds are concurrency-capped (default 2 at a time)
- Deploys are serialized per app — no two deploys of the same app race
- A failed build never affects the currently running app
- Under blue/green, a failed deploy never affects it either — the new version is discarded and the old one keeps serving
- Deploy jobs get a 30-minute timeout, comfortably covering a cold build plus the health gate, and a failure is persisted even if the job’s context was cancelled
- On startup, any deployment stuck in a non-terminal state for over 15 minutes — the residue of a crash or restart mid-deploy — is failed with a clear reason; more recent ones are resumed by the job queue
- Transient job failures are retried with backoff; failed deploys preserve logs and never corrupt platform state
Image retention
After each deploy — and again daily — Cargo prunes anything outside the newest five deployments per app, so build images don’t accumulate on disk. Rollback targets within that window always have their image available. An image is never removed while something still runs it — that covers a rollback (whose image belongs to an older deployment row) and a blue/green hand-off (where two colors run different images at once). The disk guardrail reclaims dangling images if space gets tight anyway.
Zero-downtime deploys
By default Cargo deploys blue/green: the new version is started beside the running one and only takes over once it is healthy. The old version keeps answering every request until then.
Each app alternates between two colors. A deploy always targets the idle one, so the version that is currently serving is never touched until the new one has proven itself.
If the new version never becomes healthy, Cargo removes it and leaves the
old one serving. The deployment ends failed — there is nothing to roll back,
because the running app was never replaced.
The very first blue/green deploy of an app that predates this feature is a
one-time exception: the old container is retired before the first color starts,
so that deploy has the same brief gap as recreate. Every deploy after it is a
true hand-off.
Choosing a strategy
Set it per app under Settings → Deploy strategy, or instance-wide with
CARGO_DEPLOY_STRATEGY (see Configuration).
| Strategy | Behaviour |
|---|---|
bluegreen (default) |
New version starts alongside the old one; traffic switches only after it’s healthy |
recreate |
Container is replaced in place; brief downtime per deploy |
During the hand-off both colors are in Traefik's backend pool, and it is Traefik's healthcheck that keeps a still-booting container out of rotation. Without a healthcheck path there is nothing to probe, so a request can briefly reach the new version before it is ready. Blue/green still works — but set a path to get the full guarantee.
Blue/green runs two instances of your app at the same time for a few
seconds. Choose recreate if that isn't safe — for example an app
that runs schema migrations on boot, holds an exclusive lock, or is a
singleton worker. It also briefly doubles the app's memory and CPU footprint,
which counts against its resource limits.
Rollback
From app → Deployments, pick any previous live or superseded
deployment and hit Rollback. Rollback redeploys that deployment’s
retained image without rebuilding, so service is restored within seconds
(target: ≤ 1 minute).
A rollback is an ordinary deployment, so it uses the app’s strategy too: under blue/green it hands back over with no downtime.
A failed deploy alerts the org’s owners and admins — see Operations & Hardening.
Worker hosts
Apps can be deployed to remote machines registered as worker hosts under Admin → Worker hosts. Each worker runs its own Traefik/proxy stack and is reachable over SSH. Blue/green deploys work identically on workers.
SSE stream limits
Live log streams are capped per-user (8) and per-instance (64). Access is revalidated every minute — revoked or expired sessions drop their streams immediately.