Push, build, cut over, live

Deploys

A deploy takes your source (or a pinned image) and updates one Kubernetes Deployment with a rolling update. Kubernetes keeps ready old replicas serving while the new revision becomes ready. Every deploy is recorded as an immutable history entry you can inspect and roll back to.

The deploy lifecycle

A deploy moves through a fixed set of states:

State What's happening
Building The image is being built (from a Dockerfile or source) or pulled. With deploy intents, this state appears from the first second of CI.
Release Your release_command runs once, before cutover — migrations, asset prep. If it fails, the deploy stops here and the old version keeps serving.
Running The Deployment's current generation completed its rolling update. For an enrolled app, every desired replica passed its configured TCP or HTTP readiness probe and the requested image is running.
Succeeded The cutover completed and the new version is live.
Failed A build, release, or rollout failed. Ready old replicas can continue serving while Kubernetes refuses to complete a broken new revision.

Readiness and observed health

New apps explicitly created as HTTP services with a positive container port default to TCP readiness. Apps created from a template whose primary port is labelled HTTP or HTTPS do too. Existing apps stay unenrolled until you choose disabled, tcp, or http; HTTP mode requires an absolute app-specific path such as /health. A change takes effect on the next deploy. Flicker does not add an automatic liveness probe, so a mistuned health path cannot restart-loop your container.

The app's top-level status remains lifecycle state for compatibility. Existing API responses also include nested observed health with healthy, unhealthy, or unknown, its check time, and staleness. CLI lists label these separately as HEALTH, CHECKED, and LIFECYCLE. A stale or never-run check never appears healthy.

Building from the first second of CI

Normally a deploy only becomes visible when CI finally calls Flicker — minutes into the pipeline. Deploy intents fix that. CI opens an intent at workflow start, so the deploy shows as Building from the very first second, carrying the commit, the actor, and the CI run URL. When the build finishes and the real deploy lands, the worker attaches to that same intent — giving you one continuous record from git push to rollout instead of a row that appears only at the end.

An abandoned intent (a CI run that died before deploying) stays in history as Building rather than being silently adopted by an unrelated later deploy — so the timeline always tells the truth.

Two deploy modes

One command, two ways to point it at your code:

$ flicker deploy                 # manifest mode — pinned image or [build] repo (CI)
$ flicker deploy --from-local    # tar the working dir, build on host (dev)

Manifest mode deploys exactly what's pinned in flicker.toml — a registry image, or a git repo + ref the host clones and builds. Reproducible and reviewable in a PR — the right primary for CI. Local mode tars your working directory (including uncommitted changes), ships it over, and builds it on the host — the "deploy what I have right now" path for development. Both converge on the same cutover.

Deploy history

Every deploy writes an immutable history entry with its state transitions, the image it ran, and a link to its build and deploy logs. The current status is a cheap denormalized cache; the event log is the source of truth, and historical rows are never mutated. The app page surfaces this timeline so you can see what shipped, when, and from which commit.

From the CLI, tail a running deploy's container logs:

$ flicker app logs web

Rollback via the Registry

Because every deploy stamps the exact image ref it ran, rolling back is just deploying a previous image. The app's Registry lists the images prior deploys used; pick the last good one and redeploy it:

$ flicker app deploy web --image myorg/web:v2
# re-run the same rolling cutover with the previous image

The rollback runs through the identical rolling cutover as a forward deploy — if the old image doesn't come up, the current version keeps serving. Rollback is a deploy, so it's recorded in history like any other.